Example #1
0
int
X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
{
	int ret = 0;
	BIO *in = NULL;
	int i, count = 0;
	X509 *x = NULL;

	if (file == NULL)
		return (1);
	in = BIO_new(BIO_s_file_internal());

	if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
		X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB);
		goto err;
	}

	if (type == X509_FILETYPE_PEM) {
		for (;;) {
			x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
			if (x == NULL) {
				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
				    PEM_R_NO_START_LINE) && (count > 0)) {
					ERR_clear_error();
					break;
				} else {
					X509err(X509_F_X509_LOAD_CERT_FILE,
					    ERR_R_PEM_LIB);
					goto err;
				}
			}
			i = X509_STORE_add_cert(ctx->store_ctx, x);
			if (!i)
				goto err;
			count++;
			X509_free(x);
			x = NULL;
		}
		ret = count;
	} else if (type == X509_FILETYPE_ASN1) {
		x = d2i_X509_bio(in, NULL);
		if (x == NULL) {
			X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB);
			goto err;
		}
		i = X509_STORE_add_cert(ctx->store_ctx, x);
		if (!i)
			goto err;
		ret = i;
	} else {
		X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE);
		goto err;
	}
err:
	if (x != NULL)
		X509_free(x);
	if (in != NULL)
		BIO_free(in);
	return (ret);
}
Example #2
0
X509* VSslServer::loadCrt(VError& error, QString fileName)
{
  BIO* bio = BIO_new(BIO_s_file());
  if (bio == NULL)
  {
    QString msg = "BIO_s_file return NULL";
    LOG_ERROR("%s", qPrintable(msg));
    error = VSslError(msg, VSslError::IN_BIO_S_FILE);
    BIO_free(bio);
    return NULL;
  }

  long res = BIO_read_filename(bio, qPrintable(fileName));
  if (res <= 0)
  {
    QString msg = QString("BIO_read_filename(%1) %2").arg(fileName).arg(res);
    LOG_ERROR("%s", qPrintable(msg));
    error = VSslError(msg, VSslError::IN_BIO_READ_FILENAME);
    BIO_free(bio);
    return NULL;
  }

  X509* crt = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
  if (crt == NULL)
  {
    QString msg = "PEM_read_bio_X509_AUX return NULL";
    LOG_ERROR("%s", qPrintable(msg));
    error = VSslError(msg, VSslError::IN_PEM_READ_BIO_X509_AUX);
    BIO_free(bio);
    return NULL;
  }

  BIO_free(bio);
  return crt;
}
Example #3
0
static int verify(char *file,void *in,int ilen,void *sig,int slen)
{
	int r=FILEFAIL;
	BIO *cert;
	X509 *x509;
	EVP_PKEY *key;
	EVP_MD_CTX *mdc;

	if(!(cert=BIO_new(BIO_s_file())))goto err1;
	if(BIO_read_filename(cert,file)<=0)goto err2;

	r=CRYPTOFAIL;
	if(!(x509=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL)))goto err2;
	if(!(key=X509_get_pubkey(x509)))goto err3;
	if(!(mdc=EVP_MD_CTX_create()))goto err4;
	if(EVP_DigestInit_ex(mdc,EVP_sha256(),NULL)!=1)goto err5;
	if(EVP_DigestVerifyInit(mdc,NULL,EVP_sha256(),NULL,key)!=1)goto err5;
	if(EVP_DigestVerifyUpdate(mdc,in,ilen)!=1)goto err5;
	if(EVP_DigestVerifyFinal(mdc,sig,slen)!=1)goto err5;
	r=OK;

err5:	EVP_MD_CTX_destroy(mdc);
err4:	EVP_PKEY_free(key);
err3:	X509_free(x509);
err2:	BIO_free(cert);
err1:	return r;
}
Example #4
0
/**
 * Retrieves an X509 certificate from the specified file.
 *
 * @param pemfile The filename.
 * @returns An X509 certificate.
 */
shared_ptr<X509> GetX509Certificate(const String& pemfile)
{
	X509 *cert;
	BIO *fpcert = BIO_new(BIO_s_file());

	if (fpcert == NULL) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("BIO_new")
		    << errinfo_openssl_error(ERR_get_error()));
	}

	if (BIO_read_filename(fpcert, pemfile.CStr()) < 0) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("BIO_read_filename")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(pemfile));
	}

	cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL);
	if (cert == NULL) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("PEM_read_bio_X509_AUX")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(pemfile));
	}

	BIO_free(fpcert);

	return shared_ptr<X509>(cert, X509_free);
}
Example #5
0
static int reload_pem_cert(struct openconnect_info *vpninfo)
{
	BIO *b = BIO_new(BIO_s_file_internal());
	char buf[200];

	if (!b)
		return -ENOMEM;

	if (BIO_read_filename(b, vpninfo->cert) <= 0) {
	err:
		BIO_free(b);
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to reload X509 cert for expiry check\n"));
		openconnect_report_ssl_errors(vpninfo);
		return -EIO;
	}
	vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, NULL, NULL);
	BIO_free(b);
	if (!vpninfo->cert_x509)
		goto err;

	X509_NAME_oneline(X509_get_subject_name(vpninfo->cert_x509), buf, sizeof(buf));
	vpn_progress(vpninfo, PRG_INFO,
			     _("Using client certificate '%s'\n"), buf);

	return 0;
}
Example #6
0
Certificate *Certificate::fromPEM(const char *pem)
{
	X509 *x = NULL;
	Certificate *c = NULL;
        int ret = 0;

	BIO *bp = BIO_new(BIO_s_mem());
	
	if (!bp)
		return NULL;
	
        ret = BIO_puts(bp, pem);
        
	if (!ret)
		goto done;

        x = PEM_read_bio_X509_AUX(bp, NULL, 0, NULL);
        
	if (x) {
		c = new Certificate(x);
	}
done:
	BIO_free(bp);
	
	return c;
}
Example #7
0
int
SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *data, int data_len)
{
	pem_password_cb *psw_fn = ctx->default_passwd_callback;
	void *psw_arg = ctx->default_passwd_callback_userdata;
	X509 *cert;
	BIO *bio = NULL;
	int ok;

	ERR_clear_error();

	/* Read from memory */
	bio = BIO_new_mem_buf(data, data_len);
	if (!bio) {
		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
		goto failed;
	}

	/* Load primary cert */
	cert = PEM_read_bio_X509_AUX(bio, NULL, psw_fn, psw_arg);
	if (!cert) {
		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
		goto failed;
	}

	/* Increments refcount */
	ok = SSL_CTX_use_certificate(ctx, cert);
	X509_free(cert);
	if (!ok || ERR_peek_error())
		goto failed;

	/* Load extra certs */
	ok = SSL_CTX_clear_extra_chain_certs(ctx);
	while (ok) {
		cert = PEM_read_bio_X509(bio, NULL, psw_fn, psw_arg);
		if (!cert) {
			/* Is it EOF? */
			unsigned long err = ERR_peek_last_error();
			if (ERR_GET_LIB(err) != ERR_LIB_PEM)
				break;
			if (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)
				break;

			/* On EOF do successful exit */
			BIO_free(bio);
			ERR_clear_error();
			return 1;
		}
		/* Does not increment refcount */
		ok = SSL_CTX_add_extra_chain_cert(ctx, cert);
		if (!ok)
			X509_free(cert);
	}
failed:
	if (bio)
		BIO_free(bio);
	return 0;
}
Example #8
0
/*
 * convert the RSA public key in the X.509 certificate in the BIO pointed to
 * by "input" to a JSON Web Key object
 */
static apr_byte_t apr_jwk_rsa_bio_to_key(apr_pool_t *pool, BIO *input,
		apr_jwk_key_rsa_t **jwk_key_rsa, int is_private_key) {

	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	apr_byte_t rv = FALSE;

	if (is_private_key) {
		/* get the private key struct from the BIO */
		if ((pkey = PEM_read_bio_PrivateKey(input, NULL, NULL, NULL)) == NULL)
			goto end;
	} else {
		/* read the X.509 struct */
		if ((x509 = PEM_read_bio_X509_AUX(input, NULL, NULL, NULL)) == NULL)
			goto end;
		/* get the public key struct from the X.509 struct */
		if ((pkey = X509_get_pubkey(x509)) == NULL)
			goto end;
	}

	/* allocate space */
	*jwk_key_rsa = apr_pcalloc(pool, sizeof(apr_jwk_key_rsa_t));
	apr_jwk_key_rsa_t *key = *jwk_key_rsa;

	/* get the RSA key from the public key struct */
	RSA *rsa = EVP_PKEY_get1_RSA(pkey);
	if (rsa == NULL)
		goto end;

	/* convert the modulus bignum in to a key/len */
	key->modulus_len = BN_num_bytes(rsa->n);
	key->modulus = apr_pcalloc(pool, key->modulus_len);
	BN_bn2bin(rsa->n, key->modulus);

	/* convert the exponent bignum in to a key/len */
	key->exponent_len = BN_num_bytes(rsa->e);
	key->exponent = apr_pcalloc(pool, key->exponent_len);
	BN_bn2bin(rsa->e, key->exponent);

	/* convert the private exponent bignum in to a key/len */
	if (rsa->d != NULL) {
		key->private_exponent_len = BN_num_bytes(rsa->d);
		key->private_exponent = apr_pcalloc(pool, key->private_exponent_len);
		BN_bn2bin(rsa->d, key->private_exponent);
	}

	rv = TRUE;

end:

	if (pkey)
		EVP_PKEY_free(pkey);
	if (x509)
		X509_free(x509);

	return rv;
}
Example #9
0
static X509 *load_cert(const char *pPath)
{
    X509 *pCert;
    BIO *bio = BIO_new_file(pPath, "r");
    if (bio == NULL)
        return NULL;
    pCert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return pCert;
}
Example #10
0
int main(int argc, char **argv)
{
    X509  *x509 = NULL;
    BIO   *bio  = NULL;
    has_t *crt  = NULL;
    char  *json = NULL; 
    size_t l;

    openssl_init();

    if ((bio = BIO_new(BIO_s_file())) == NULL) {
        return -1;
    }

    if(argc < 2) {
        BIO_set_fp(bio, stdin, BIO_NOCLOSE);
    } else {
        BIO_read_filename(bio, argv[1]);
    }
    
    /* Format DER */
    if((x509 = d2i_X509_bio(bio, NULL)) == NULL) {
        ERR_clear_error();
        BIO_reset(bio);
        /* Format PEM */
        x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
    }

    if(!x509) {
        fprintf(stderr, "Error loading certificate\n");
        return -1;
    }

    if((crt = has_x509_new(x509)) == NULL) {
        fprintf(stderr, "Error converting certificate\n");
        return -1;
    } 

    if(has_json_serialize(crt, &json, &l, HAS_JSON_SERIALIZE_PRETTY) == 0) {
        printf("%s\n", json);
        free(json);
    } else {
        fprintf(stderr, "Error serializing certificate\n");
        return -1;        
    }

    has_free(crt);
    X509_free(x509);
    BIO_free(bio);

    openssl_cleanup();

    return 0;
}
X509 *TS_CONF_load_cert(const char *file)
	{
	BIO *cert = NULL;
	X509 *x = NULL;

	if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
end:
	if (x == NULL)
		TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "unable to load certificate: %s\n", file);
	BIO_free(cert);
	return x;
	}
Example #12
0
X509 *TS_CONF_load_cert(const char *file)
	{
	BIO *cert = NULL;
	X509 *x = NULL;

	if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
end:
	if (x == NULL)
		fprintf(stderr, "unable to load certificate: %s\n", file);
	BIO_free(cert);
	return x;
	}
Example #13
0
X509 *TS_CONF_load_cert(const char *file)
{
    BIO *cert = NULL;
    X509 *x = NULL;

    if ((cert = BIO_new_file(file, "r")) == NULL)
        goto end;
    x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
 end:
    if (x == NULL)
        TSerr(TS_F_TS_CONF_LOAD_CERT, TS_R_CANNOT_LOAD_CERT);
    BIO_free(cert);
    return x;
}
Example #14
0
bool load_pem_key(const char *p_data, uint32_t p_length, RSA_KEYTYPE p_type, const char *p_passphrase, EVP_PKEY *&r_key)
{
	bool t_success = true;
	BIO *t_data = NULL;
	EVP_PKEY *t_key = NULL;
	t_data = BIO_new_mem_buf((void*)p_data, p_length);
	t_success = t_data != NULL;
	char t_empty_pass[] = "";
	char *t_passphrase = (p_passphrase != NULL) ? (char*)p_passphrase : t_empty_pass;

	if (t_success)
	{
		switch (p_type)
		{
		case RSAKEY_PUBKEY:
			t_key = PEM_read_bio_PUBKEY(t_data, NULL, NULL, t_passphrase);
			t_success = (t_key != NULL);
			break;
		case RSAKEY_PRIVKEY:
			t_key = PEM_read_bio_PrivateKey(t_data, NULL, NULL, t_passphrase);
			t_success = (t_key != NULL);
			break;
		case RSAKEY_CERT:
			{
				X509* t_cert = NULL;
				t_cert = PEM_read_bio_X509_AUX(t_data, NULL, NULL, t_passphrase);
				t_success = (t_cert != NULL);
				if (t_success)
				{
					t_key = X509_get_pubkey(t_cert);
					t_success = (t_key != NULL);
					X509_free(t_cert);
				}
			}
			break;
		default:
			// error: unknown key type
			t_success = false;
		}
	}

	if (t_data != NULL)
		BIO_free(t_data);
	if (t_success)
		r_key = t_key;

	return t_success;
}
Example #15
0
static X509 *st_tls_load_cert(const char *file)
{
    X509 *x=NULL;
    BIO *cert;

    if ((cert=BIO_new(BIO_s_file())) == NULL)
        goto end;

    if (BIO_read_filename(cert,file) <= 0)
        goto end;

    x=PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
end:
    if (cert != NULL) BIO_free(cert);
    return(x);
}
Example #16
0
// load certificate from file to a OpenSSL object
X509 *load_cert(char *filename)
{
    BIO* f;
    X509 *ret;

    f = BIO_new(BIO_s_file());
    BIO_read_filename(f, filename);

    ret = PEM_read_bio_X509_AUX(f, NULL, 0, NULL);
    if (ret == NULL)
        fprintf(stderr, "Unable to load file %s as X509 certificate\n", filename);

    BIO_free_all(f);

    return ret;
}
Example #17
0
// Adds a buffer containing one or more PEM-encoded
// root certificates to the X509PEMVerifier.
//
// If the certificate (or one of the certificates) could not be
// parsed AddPEM will return immediately, resulting in all of the
// certificates up to the bad certicate being added to the verifier.
bool X509PEMVerifier::AddPEM(const ByteArray &buf) {
	BIO *mem = BIO_new_mem_buf(static_cast<void *>(const_cast<char *>(buf.ConstData())), buf.Length());
	(void) BIO_set_close(mem, BIO_NOCLOSE);

	int ncerts = 0;
	while (1) {
		X509 *x = PEM_read_bio_X509_AUX(mem, nullptr, nullptr, nullptr);
		if (x == nullptr) {
			return false;
		}
		X509_STORE_add_cert(store_, x);
		X509_free(x);
		ncerts++;
	}

	return true;
}
Example #18
0
X509 *load_cert(BIO * err, const char *file, int format,
                const char *pass, ENGINE * e, const char *cert_descrip)
{
  ASN1_HEADER *ah = NULL;
  BUF_MEM *buf = NULL;
  X509 *x = NULL;
  BIO *cert;

  if ((cert = BIO_new(BIO_s_file())) == NULL)
    {
      ERR_print_errors(err);
      goto end;
    }

  if (file == NULL)
    {
      setvbuf(stdin, NULL, _IONBF, 0);
      BIO_set_fp(cert, stdin, BIO_NOCLOSE);
    }
  else
    {
      if (BIO_read_filename(cert, file) <= 0)
        {
          BIO_printf(err, "Error opening %s %s\n", cert_descrip, file);
          ERR_print_errors(err);
          goto end;
        }
    }

  if (format == FORMAT_PEM)
    x = PEM_read_bio_X509_AUX(cert, NULL, (pem_password_cb *) NULL, NULL);
end:
  if (x == NULL)
    {
      BIO_printf(err, "unable to load certificate\n");
      ERR_print_errors(err);
    }
  if (ah != NULL)
    ASN1_HEADER_free(ah);
  if (cert != NULL)
    BIO_free(cert);
  if (buf != NULL)
    BUF_MEM_free(buf);
  return (x);
}
Example #19
0
/* Based on Node's SSL_CTX_use_certificate_chain, in src/node_crypto.cc */
selene_error_t *read_certificate_chain(selene_conf_t *conf, BIO *in,
                                       selene_cert_chain_t **p_certs) {
  X509 *x = NULL;
  selene_cert_chain_t *chain;
  selene_cert_t *tmpc;

  x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);

  if (x == NULL) {
    return selene_error_create(SELENE_ENOMEM, "Failed to parse certificate");
  }

  SELENE_ERR(sln_cert_chain_create(conf, &chain));
  SELENE_ERR(sln_cert_create(conf, x, 0, &tmpc));
  SLN_CERT_CHAIN_INSERT_TAIL(chain, tmpc);

  {
    /**
     * If we could set up our certificate, now proceed to
     * the CA certificates.
     */
    X509 *ca;
    unsigned long err;

    while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
      SELENE_ERR(sln_cert_create(conf, ca, 0, &tmpc));
      SLN_CERT_CHAIN_INSERT_TAIL(chain, tmpc);
    }

    /* When the while loop ends, it's usually just EOF. */
    err = ERR_peek_last_error();
    if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
        ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
      ERR_clear_error();
    } else {
      /* some real error */
      /* TODO: handle parse errors of the ca certs */
      ERR_clear_error();
    }
  }

  *p_certs = chain;

  return SELENE_SUCCESS;
}
Example #20
0
/*
 * Read a bio that contains our certificate in "PEM" format,
 * possibly followed by a sequence of CA certificates that should be
 * sent to the peer in the Certificate message.
 */
static int
ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
{
	X509 *ca, *x = NULL;
	unsigned long err;
	int ret = 0;

	if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
	    ctx->default_passwd_callback_userdata)) == NULL) {
		SSLerrorx(ERR_R_PEM_LIB);
		goto err;
	}

	if (!SSL_CTX_use_certificate(ctx, x))
		goto err;

	if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
		goto err;

	/* Process any additional CA certificates. */
	while ((ca = PEM_read_bio_X509(in, NULL,
	    ctx->default_passwd_callback,
	    ctx->default_passwd_callback_userdata)) != NULL) {
		if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
			X509_free(ca);
			goto err;
		}
	}

	/* When the while loop ends, it's usually just EOF. */
	err = ERR_peek_last_error();
	if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
	    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
		ERR_clear_error();
		ret = 1;
	}

 err:
	X509_free(x);

	return (ret);
}
Example #21
0
static PyObject *
PySSL_test_decode_certificate (PyObject *mod, PyObject *args) {

	PyObject *retval = NULL;
	char *filename = NULL;
	X509 *x=NULL;
	BIO *cert;
	int verbose = 1;

	if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate",
                              &filename, &verbose))
		return NULL;

	if ((cert=BIO_new(BIO_s_file())) == NULL) {
		PyErr_SetString(PySSLErrorObject,
                                "Can't malloc memory to read file");
		goto fail0;
	}

	if (BIO_read_filename(cert,filename) <= 0) {
		PyErr_SetString(PySSLErrorObject,
                                "Can't open file");
		goto fail0;
	}

	x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
	if (x == NULL) {
		PyErr_SetString(PySSLErrorObject,
                                "Error decoding PEM-encoded file");
		goto fail0;
	}

	retval = _decode_certificate(x, verbose);

  fail0:

	if (cert != NULL) BIO_free(cert);
	return retval;
}
Example #22
0
/* Loads an in-memory PEM certificate chain into the SSL context. */
static tsi_result ssl_ctx_use_certificate_chain(
    SSL_CTX* context, const unsigned char* pem_cert_chain,
    size_t pem_cert_chain_size) {
  tsi_result result = TSI_OK;
  X509* certificate = NULL;
  BIO* pem = BIO_new_mem_buf((void*)pem_cert_chain, pem_cert_chain_size);
  if (pem == NULL) return TSI_OUT_OF_RESOURCES;

  do {
    certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, "");
    if (certificate == NULL) {
      result = TSI_INVALID_ARGUMENT;
      break;
    }
    if (!SSL_CTX_use_certificate(context, certificate)) {
      result = TSI_INVALID_ARGUMENT;
      break;
    }
    while (1) {
      X509* certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, "");
      if (certificate_authority == NULL) {
        ERR_clear_error();
        break; /* Done reading. */
      }
      if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) {
        X509_free(certificate_authority);
        result = TSI_INVALID_ARGUMENT;
        break;
      }
      /* We don't need to free certificate_authority as its ownership has been
         transfered to the context. That is not the case for certificate though.
      */
    }
  } while (0);

  if (certificate != NULL) X509_free(certificate);
  BIO_free(pem);
  return result;
}
Example #23
0
static int
tls_keypair_pubkey_hash(struct tls_keypair *keypair, char **hash)
{
	BIO *membio = NULL;
	X509 *cert = NULL;
	char d[EVP_MAX_MD_SIZE], *dhex = NULL;
	int dlen, rv = -1;

	*hash = NULL;

	if ((membio = BIO_new_mem_buf(keypair->cert_mem,
	    keypair->cert_len)) == NULL)
		goto err;
	if ((cert = PEM_read_bio_X509_AUX(membio, NULL, tls_password_cb,
	    NULL)) == NULL)
		goto err;

	if (X509_pubkey_digest(cert, EVP_sha256(), d, &dlen) != 1)
		goto err;

	if (tls_hex_string(d, dlen, &dhex, NULL) != 0)
		goto err;

	if (asprintf(hash, "SHA256:%s", dhex) == -1) {
		*hash = NULL;
		goto err;
	}

	rv = 0;

 err:
	free(dhex);
	X509_free(cert);
	BIO_free(membio);

	return (rv);
}
Example #24
0
/*
 * Verify that a bogus user ID/password fails when
 * using HTTP digest auth.
 */
static void us898_test9 (void) 
{
    EST_CTX *ectx;
    EVP_PKEY *key;
    unsigned char *key_raw;
    int key_len;
    unsigned char *cert_raw;
    int cert_len;
    int rv;
    int pkcs7_len = 0;
    X509 *cert = NULL;
    BIO *in;
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Enable HTTP digest authentication
     */
    st_enable_http_digest_auth();

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    /*
     * Set the authentication mode to use a user id/password
     */
    rv = est_client_set_auth(ectx, "jdoe", "panthers", NULL, NULL);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    /*
     * Read in the private key
     */
    key_len = read_binary_file("US898/key-expired.pem", &key_raw);
    CU_ASSERT(key_len > 0);
    key = est_load_key(key_raw, key_len, EST_FORMAT_PEM);
    CU_ASSERT(key != NULL);
    free(key_raw);

    /*
     * Read in the old cert
     */
    cert_len = read_binary_file("US898/cert-expired.pem", &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);

    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Enroll an expired cert that contains x509 extensions.
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_AUTH_FAIL);

    est_destroy(ectx);

    /*
     * Re-enable HTTP basic authentication
     */
    st_enable_http_basic_auth();

}
Example #25
0
/*
 * Test the re-enroll API to ensure it gracefully
 * handles a null EVP_PKEY pointer.
 */
static void us898_test4 (void) 
{
    EST_CTX *ectx;
    int pkcs7_len = 0;
    int rv;
    X509 *cert = NULL;
    unsigned char *cert_raw;
    int cert_len;
    BIO *in;
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    /*
     * Set the authentication mode to use a user id/password
     */
    rv = est_client_set_auth(ectx, US898_UID, US898_PWD, NULL, NULL);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    /*
     * Read in an old cert that we can use for re-enroll
     */
    cert_len = read_binary_file("US898/cert-expired.pem", &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);

    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * re-enroll using a null EVP_KEY pointer.
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, NULL);
    CU_ASSERT(rv == EST_ERR_NO_KEY);

    /*
     * Clean up
     */
    X509_free(cert);
    est_destroy(ectx);
}
Example #26
0
/*
 * This test case uses an existing expired cert and
 * attempts to re-enroll it.  The expired certs contains
 * several X509 extensions. We verify the new issued
 * cert preserves these extensions using grep.  Note, 
 * preserving these extensions requires the OpenSSL CA
 * to enable the "copy_extensions" knob in the OpenSSL
 * config file.  This is why this test suite uses a
 * unique copy of estExampleCA.cnf.
 */
static void us898_test2 (void) 
{
    EST_CTX *ectx;
    EVP_PKEY *key;
    unsigned char *key_raw;
    int key_len;
    unsigned char *cert_raw;
    int cert_len;
    int rv;
    int pkcs7_len = 0;
    unsigned char *new_cert = NULL;
    X509 *cert = NULL;
    BIO *in;
    char cmd[200];
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    /*
     * Set the authentication mode to use a user id/password
     */
    rv = est_client_set_auth(ectx, US898_UID, US898_PWD, NULL, NULL);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    /*
     * Read in the private key
     */
    key_len = read_binary_file("US898/key-expired.pem", &key_raw);
    CU_ASSERT(key_len > 0);
    key = est_load_key(key_raw, key_len, EST_FORMAT_PEM);
    CU_ASSERT(key != NULL);
    free(key_raw);

    /*
     * Read in the old cert
     */
    cert_len = read_binary_file("US898/cert-expired.pem", &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);

    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Enroll an expired cert that contains x509 extensions.
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Retrieve the cert that was given to us by the EST server
     */
    if (rv == EST_ERR_NONE) {
	new_cert = malloc(pkcs7_len);
	CU_ASSERT(new_cert != NULL);
	rv = est_client_copy_enrolled_cert(ectx, new_cert);
	CU_ASSERT(rv == EST_ERR_NONE);
    }

    /*
     * Save the cert to a local file
     */
    rv = write_binary_file(US898_TC2_CERT_B64, new_cert, pkcs7_len);
    CU_ASSERT(rv == 1);

    /*
     * Base 64 decode the cert response
     */
    sprintf(cmd, "openssl base64 -d -in %s -out %s", US898_TC2_CERT_B64, US898_TC2_CERT_PK7);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Convert the pkcs7 cert to a PEM cert
     */
    sprintf(cmd, "openssl pkcs7 -in %s -inform DER -print_certs -out %s", US898_TC2_CERT_PK7, US898_TC2_CERT_PEM);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Convert PEM cert to a textual representation of the cert
     */
    sprintf(cmd, "openssl x509 -text -in %s > %s", US898_TC2_CERT_PEM, US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Verify the jimbob DNS extension was preserved
     */
    sprintf(cmd, "grep jimbob %s", US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Verify the bobcat DNS extension was preserved
     */
    sprintf(cmd, "grep bobcat %s", US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Verify the IP address extension was preserved
     */
    sprintf(cmd, "grep 172 %s", US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Verify the Repudiation key usage extension was preserved
     */
    sprintf(cmd, "grep Repudiation %s", US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Verify the public key was preserved
     */
    sprintf(cmd, "grep '00:e3:ca:38:65:fb:9c:46:a6:22:b1:be:17:bc:50' %s", US898_TC2_CERT_TXT);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Clean up
     */
    if (new_cert) free(new_cert);
    est_destroy(ectx);
}
Example #27
0
/*
 * Verify the client fails authentication when the
 * client sends an identy cert which doesn't match 
 * the trust anchor. 
 */
static void us898_test12 (void) 
{
    EST_CTX *ectx;
    EVP_PKEY *key;
    unsigned char *key_raw;
    int key_len;
    unsigned char *cert_raw;
    int cert_len;
    int rv;
    int pkcs7_len = 0;
    X509 *cert = NULL;
    BIO *in;
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    
    /*
     * Read in the private key
     */
    key_len = read_binary_file(US898_TC12_KEY, &key_raw);
    CU_ASSERT(key_len > 0);
    key = est_load_key(key_raw, key_len, EST_FORMAT_PEM);
    CU_ASSERT(key != NULL);
    free(key_raw);

    /*
     * Read in the old cert
     */
    cert_len = read_binary_file(US898_TC12_CERT, &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);


    /*
     * Set the authentication mode to use cert for re-enroll.
     * This should return an error since the certificate doesn't
     * match the trust anchor. 
     */
    rv = est_client_set_auth(ectx, NULL, NULL, cert, key);
    CU_ASSERT(rv == EST_ERR_CERT_VERIFICATION);

    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    
    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Enroll a bad cert. The client should reject this cert. 
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_CERT_VERIFICATION);
}
Example #28
0
/*
 * Verify the server fails authentication when the
 * client sends an expired identy cert and uses 
 * valid HTTP auth credentials.
 */
static void us898_test11 (void) 
{
    int rv;
    EST_CTX *ectx;
    EVP_PKEY *key;
    unsigned char *key_raw;
    int key_len;
    unsigned char *cert_raw;
    int cert_len;
    int pkcs7_len = 0;
    X509 *cert = NULL;
    BIO *in;
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    /*
     * Read in the private key
     */
    key_len = read_binary_file(US898_TC11_KEY, &key_raw);
    CU_ASSERT(key_len > 0);
    key = est_load_key(key_raw, key_len, EST_FORMAT_PEM);
    CU_ASSERT(key != NULL);
    free(key_raw);

    /*
     * Read in the old cert
     */
    cert_len = read_binary_file(US898_TC11_CERT, &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);


    /*
     * Set the authentication mode to use the expired certificate 
     * and valid HTTP auth credentials.
     */
    rv = est_client_set_auth(ectx, US898_UID, US898_PWD, cert, key);
    CU_ASSERT(rv == EST_ERR_NONE);
    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_SSL_CONNECT);

    /*
     * Re-Enroll the cert 
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_SSL_CONNECT);

    est_destroy(ectx);
}
Example #29
0
/*
 * Verify the server fails authentication when the
 * client sends a valid identity cert but doesn't 
 * provide HTTP auth credentials.
 */
static void us898_test10 (void) 
{
    char cmd[200];
    int rv;
    EST_CTX *ectx;
    EVP_PKEY *key;
    unsigned char *key_raw;
    int key_len;
    unsigned char *cert_raw;
    int cert_len;
    int pkcs7_len = 0;
    X509 *cert = NULL;
    BIO *in;
    unsigned char *attr_data = NULL;
    int attr_len;

    LOG_FUNC_NM;

    /*
     * Create a CSR
     */
    sprintf(cmd, "openssl req -new -nodes -out %s -newkey rsa:2048 -keyout %s -subj /CN=127.0.0.1 "
	    "-config CA/estExampleCA.cnf", 
	    US898_TC10_CSR, US898_TC10_KEY);  
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Sign the CSR using our local CA
     */
    sprintf(cmd, "openssl ca -out %s -batch -config CA/estExampleCA.cnf -infiles %s", 
	    US898_TC10_CERT, US898_TC10_CSR);
    rv = system(cmd);
    CU_ASSERT(rv == 0);

    /*
     * Create a client context 
     */
    ectx = est_client_init(cacerts, cacerts_len, 
                           EST_CERT_FORMAT_PEM,
                           client_manual_cert_verify);
    CU_ASSERT(ectx != NULL);

    /*
     * Read in the private key
     */
    key_len = read_binary_file(US898_TC10_KEY, &key_raw);
    CU_ASSERT(key_len > 0);
    key = est_load_key(key_raw, key_len, EST_FORMAT_PEM);
    CU_ASSERT(key != NULL);
    free(key_raw);

    /*
     * Read in the old cert
     */
    cert_len = read_binary_file(US898_TC10_CERT, &cert_raw);
    CU_ASSERT(cert_len > 0);
    in = BIO_new_mem_buf(cert_raw, cert_len);
    CU_ASSERT(in != NULL);
    if (!in) return;
    cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
    CU_ASSERT(cert != NULL);
    if (!cert) return; 
    BIO_free_all(in);
    free(cert_raw);


    /*
     * Set the authentication mode to use the certificate 
     * No HTTP auth credentials are provided.
     */
    rv = est_client_set_auth(ectx, NULL, NULL, cert, key);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Set the EST server address/port
     */
    est_client_set_server(ectx, US898_SERVER_IP, US898_SERVER_PORT);

    /*
     * Get the latest CSR attributes
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    CU_ASSERT(rv == EST_ERR_NONE);

    /*
     * Enroll a cert, should fail because we 
     * didn't provide valid HTTP auth credentials
     */
    rv = est_client_enroll(ectx, "TC-US898-10", &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_AUTH_FAIL);

    /*
     * Re-Enroll the cert, should work since
     * we provide a valid cert to identify ourselves
     * and HTTP auth isn't required for re-enroll even when
     * the server has enabled HTTP auth.
     */
    rv = est_client_reenroll(ectx, cert, &pkcs7_len, key);
    CU_ASSERT(rv == EST_ERR_NONE);

    est_destroy(ectx);
}
Example #30
0
static int load_certificate(struct openconnect_info *vpninfo)
{
	if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) ||
	    !strncmp(vpninfo->cert, "pkcs11:", 7)) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("This binary built without PKCS#11 support\n"));
		return -EINVAL;
	}

	vpn_progress(vpninfo, PRG_TRACE,
		     _("Using certificate file %s\n"), vpninfo->cert);

	if (strncmp(vpninfo->cert, "keystore:", 9) &&
	    (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
	     vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
		FILE *f;
		PKCS12 *p12;

		f = fopen(vpninfo->cert, "r");
		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open certificate file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}
		p12 = d2i_PKCS12_fp(f, NULL);
		fclose(f);
		if (p12)
			return load_pkcs12_certificate(vpninfo, p12);

		/* Not PKCS#12 */
		if (vpninfo->cert_type == CERT_TYPE_PKCS12) {
			vpn_progress(vpninfo, PRG_ERR, _("Read PKCS#12 failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		/* Clear error and fall through to see if it's a PEM file... */
		ERR_clear_error();
	}

	/* It's PEM or TPM now, and either way we need to load the plain cert: */
#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->cert, "keystore:", 9)) {
		BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert);
		if (!b)
			return -EINVAL;
		vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!vpninfo->cert_x509) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to load X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
	} else
#endif /* ANDROID_KEYSTORE */
	{
		if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx,
							vpninfo->cert)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Loading certificate failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}

		/* Ew, we can't get it back from the OpenSSL CTX in any sane fashion */
		reload_pem_cert(vpninfo);
	}

#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
		EVP_PKEY *key;
		BIO *b;

	again_android:
		b = BIO_from_keystore(vpninfo, vpninfo->sslkey);
		if (!b)
			return -EINVAL;
		key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!key) {
			if (is_pem_password_error(vpninfo))
				goto again_android;
			return -EINVAL;
		}
		if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use private key from keystore\n"));
			EVP_PKEY_free(key);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
		return 0;
	}
#endif /* ANDROID_KEYSTORE */

	if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
		FILE *f = fopen(vpninfo->sslkey, "r");
		char buf[256];

		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open private key file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}

		buf[255] = 0;
		while (fgets(buf, 255, f)) {
			if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) {
				vpninfo->cert_type = CERT_TYPE_TPM;
				break;
			} else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n")) {
				vpninfo->cert_type = CERT_TYPE_PEM;
				break;
			}
		}
		fclose(f);
		if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to identify private key type in '%s'\n"),
				     vpninfo->sslkey);
			return -EINVAL;
		}
	}

	if (vpninfo->cert_type == CERT_TYPE_TPM)
		return load_tpm_certificate(vpninfo);

	/* Standard PEM certificate */
	SSL_CTX_set_default_passwd_cb(vpninfo->https_ctx, pem_pw_cb);
	SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, vpninfo);
 again:
	if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx, vpninfo->sslkey,
					    SSL_FILETYPE_PEM)) {
		if (is_pem_password_error(vpninfo))
			goto again;
		return -EINVAL;
	}
	return 0;
}