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); }
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; }
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; }
/** * 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); }
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; }
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; }
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; }
/* * 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; }
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; }
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; }
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; }
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; }
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; }
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); }
// 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; }
// 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; }
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); }
/* 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; }
/* * 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); }
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; }
/* 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; }
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); }
/* * 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(); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
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; }