void describeCertificates(SSL* ssl, bool isServer) { // Resumed sessions don't necessarily have chains (not included in session ticket) X509 *cert = SSL_get_peer_certificate(ssl); if (cert == NULL) { fprintf(stderr,"No peer certificates.\n"); } else { fprintf(stderr,"Peer certificates:\n"); describeCertificate(0, cert); X509_free(cert); STACK_OF(X509) *certs = SSL_get_peer_cert_chain(ssl); // We don't have to free this apparently // Cached sessions may not have a chain if (certs != NULL) { // On server, chain doesn't include client certificate if (isServer) { for (int i = 0; i < sk_X509_num(certs); i++) { describeCertificate(i+1, sk_X509_value(certs,i)); } } else { for (int i = 1; i < sk_X509_num(certs); i++) { describeCertificate(i, sk_X509_value(certs,i)); } } } long verify_result = SSL_get_verify_result(ssl); if (verify_result == X509_V_OK) { fprintf(stderr,"Certificate OK\n"); } else { // See 'man verify(1SSL)' for meanings of the codes fprintf(stderr,"Verification error %ld\n", verify_result); ERR_print_errors_fp(stderr); } } }
static int openssl_ocsp_request_parse(lua_State*L) { OCSP_REQUEST *req = CHECK_OBJECT(1, OCSP_REQUEST, "openssl.ocsp_request"); int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); OCSP_REQINFO *inf = req->tbsRequest; OCSP_SIGNATURE *sig = req->optionalSignature; BIO* bio = BIO_new(BIO_s_mem()); int i, num; lua_newtable(L); AUXILIAR_SET(L, -1, "version", ASN1_INTEGER_get(inf->version), integer); if (inf->requestorName) { opensl_push_general_name(L, inf->requestorName, utf8); lua_setfield(L, -2, "requestorName"); } num = sk_OCSP_ONEREQ_num(inf->requestList); lua_newtable(L); for (i = 0; i < num; i++) { OCSP_ONEREQ *one = sk_OCSP_ONEREQ_value(inf->requestList, i); OCSP_CERTID *a = one->reqCert; lua_newtable(L); { openssl_push_x509_algor(L, a->hashAlgorithm); lua_setfield(L, -2, "hashAlgorithm"); PUSH_ASN1_OCTET_STRING(L, a->issuerNameHash); lua_setfield(L, -2, "issuerNameHash"); PUSH_ASN1_OCTET_STRING(L, a->issuerKeyHash); lua_setfield(L, -2, "issuerKeyHash"); PUSH_ASN1_INTEGER(L, a->serialNumber); lua_setfield(L, -2, "serialNumber"); } lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "requestList"); if (inf->requestExtensions){ STACK_OF(X509_EXTENSION) *extensions = sk_X509_EXTENSION_dup(inf->requestExtensions); PUSH_OBJECT(extensions,"openssl.stack_of_x509_extension"); lua_setfield(L,-2, "extensions"); } if (sig) { BIO_reset(bio); X509_signature_print(bio, sig->signatureAlgorithm, sig->signature); for (i = 0; i < sk_X509_num(sig->certs); i++) { X509_print(bio, sk_X509_value(sig->certs, i)); PEM_write_bio_X509(bio, sk_X509_value(sig->certs, i)); } } BIO_free(bio); return 1; }
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) { unsigned char *p; int i; unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; BUF_MEM *buf; /* TLSv1 sends a chain with nothing in it, instead of an alert */ buf=s->init_buf; if (!BUF_MEM_grow_clean(buf,10)) { SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); return(0); } if (x != NULL) { X509_STORE_CTX xs_ctx; if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL)) { SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); return(0); } X509_verify_cert(&xs_ctx); /* Don't leave errors in the queue */ ERR_clear_error(); for (i=0; i < sk_X509_num(xs_ctx.chain); i++) { x = sk_X509_value(xs_ctx.chain, i); if (!dtls1_add_cert_to_buf(buf, &l, x)) { X509_STORE_CTX_cleanup(&xs_ctx); return 0; } } X509_STORE_CTX_cleanup(&xs_ctx); } /* Thawte special :-) */ for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) { x=sk_X509_value(s->ctx->extra_certs,i); if (!dtls1_add_cert_to_buf(buf, &l, x)) return 0; } l-= (3 + DTLS1_HM_HEADER_LENGTH); p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); l2n3(l,p); l+=3; p=(unsigned char *)&(buf->data[0]); p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); l+=DTLS1_HM_HEADER_LENGTH; return(l); }
NOEXPORT int cert_check_local(X509_STORE_CTX *callback_ctx) { X509 *cert=X509_STORE_CTX_get_current_cert(callback_ctx); X509_OBJECT obj; #if OPENSSL_VERSION_NUMBER>=0x10000000L STACK_OF(X509) *sk; int i; sk=X509_STORE_get1_certs(callback_ctx, X509_get_subject_name(cert)); if(sk) { for(i=0; i<sk_X509_num(sk); i++) if(compare_pubkeys(cert, sk_X509_value(sk, i))) { sk_X509_pop_free(sk, X509_free); return 1; /* accept */ } sk_X509_pop_free(sk, X509_free); } #endif /* pre-1.0.0 API only returns a single matching certificate */ if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509, X509_get_subject_name(cert), &obj)==1 && compare_pubkeys(cert, obj.data.x509)) return 1; /* accept */ s_log(LOG_WARNING, "CERT: Certificate not found in local repository"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REJECTED); return 0; /* reject */ }
int verify_cred( gss_cred_id_t credential) { gss_cred_id_desc * cred_handle; X509 * cert; X509 * previous_cert; int cert_count; cert_count = 1; cred_handle = (gss_cred_id_desc *) credential; if(cred_handle->pcd->cert_chain) { cert_count += sk_X509_num(cred_handle->pcd->cert_chain); } cert = cred_handle->pcd->ucert; previous_cert=NULL; cert_count--; do { if(previous_cert != NULL) { if(!X509_verify(previous_cert,X509_get_pubkey(cert))) { return 0; } } previous_cert = cert; } while(cert_count-- && (cert = sk_X509_value(cred_handle->pcd->cert_chain,cert_count))); return 1; }
/** * Return the chain of certificate of the peer. */ static int meth_getpeerchain(lua_State *L) { int i; int idx = 1; int n_certs; X509 *cert; STACK_OF(X509) *certs; p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); if (ssl->state != LSEC_STATE_CONNECTED) { lua_pushnil(L); lua_pushstring(L, "closed"); return 2; } lua_newtable(L); if (ssl->ssl->server) { lsec_pushx509(L, SSL_get_peer_certificate(ssl->ssl)); lua_rawseti(L, -2, idx++); } certs = SSL_get_peer_cert_chain(ssl->ssl); n_certs = sk_X509_num(certs); for (i = 0; i < n_certs; i++) { cert = sk_X509_value(certs, i); /* Increment the reference counting of the object. */ /* See SSL_get_peer_certificate() source code. */ CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); lsec_pushx509(L, cert); lua_rawseti(L, -2, idx++); } return 1; }
static CURLcode sslctxfun( CURL * curl, void * sslctx, void * parm ) { sslctxparm * p = (sslctxparm *) parm; SSL_CTX * ctx = (SSL_CTX *) sslctx ; if ( !SSL_CTX_use_certificate( ctx,p->usercert ) ) { BIO_printf( p->errorbio, "SSL_CTX_use_certificate problem\n" ); goto err; } if ( !SSL_CTX_use_PrivateKey( ctx,p->pkey ) ) { BIO_printf( p->errorbio, "SSL_CTX_use_PrivateKey\n" ); goto err; } if ( !SSL_CTX_check_private_key( ctx ) ) { BIO_printf( p->errorbio, "SSL_CTX_check_private_key\n" ); goto err; } SSL_CTX_set_quiet_shutdown( ctx,1 ); SSL_CTX_set_cipher_list( ctx,"RC4-MD5" ); SSL_CTX_set_mode( ctx, SSL_MODE_AUTO_RETRY ); X509_STORE_add_cert( ctx->cert_store,sk_X509_value( p->ca,sk_X509_num( p->ca ) - 1 ) ); SSL_CTX_set_verify_depth( ctx,2 ); SSL_CTX_set_verify( ctx,SSL_VERIFY_PEER,NULL ); SSL_CTX_set_cert_verify_callback( ctx, ssl_app_verify_callback, parm ); return CURLE_OK ; err: ERR_print_errors( p->errorbio ); return CURLE_SSL_CERTPROBLEM; }
json::value get_cert_chain_information(boost::asio::ssl::verify_context &verifyCtx) { X509_STORE_CTX *storeContext = verifyCtx.native_handle(); STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext); const int numCerts = sk_X509_num(certStack); if (numCerts < 0) { return {}; } json::value certChainInformation; for (int index = 0; index < numCerts; ++index) { X509 *cert = sk_X509_value(certStack, index); json::value certInformation; certInformation[U("Issuer")] = json::value::string(get_issuer_from_cert(cert)); certInformation[U("Subject")] = json::value::string(get_subject_from_cert(cert)); certInformation[U("FingerPrint")] = json::value::string(get_fingerprint_from_cert(cert)); utility::stringstream_t countInfo; countInfo << "Certificate: " << index; certChainInformation[countInfo.str()] = certInformation; } return certChainInformation; }
bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const { // can we check the certificate against a list of fingerprints? if (!fingerprints_.empty()) { X509_STORE_CTX *sctx = ctx.native_handle(); if (!sctx) { MERROR("Error getting verify_context handle"); return false; } X509* cert = nullptr; const STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(sctx); if (!chain || sk_X509_num(chain) < 1 || !(cert = sk_X509_value(chain, 0))) { MERROR("No certificate found in verify_context"); return false; } // buffer for the certificate digest and the size of the result std::vector<uint8_t> digest(EVP_MAX_MD_SIZE); unsigned int size{ 0 }; // create the digest from the certificate if (!X509_digest(cert, EVP_sha256(), digest.data(), &size)) { MERROR("Failed to create certificate fingerprint"); return false; } // strip unnecessary bytes from the digest digest.resize(size); return std::binary_search(fingerprints_.begin(), fingerprints_.end(), digest); }
// Verify the signed block, the first 32 bytes of the data must be the certificate hash to work. int __fastcall util_verify(char* signature, int signlen, struct util_cert* cert, char** data) { unsigned int size, r; BIO *out = NULL; PKCS7 *message = NULL; char* data2 = NULL; char hash[UTIL_HASHSIZE]; STACK_OF(X509) *st = NULL; cert->x509 = NULL; cert->pkey = NULL; *data = NULL; message = d2i_PKCS7(NULL, (const unsigned char**)&signature, signlen); if (message == NULL) goto error; out = BIO_new(BIO_s_mem()); // Lets rebuild the original message and check the size size = i2d_PKCS7(message, NULL); if (size < (unsigned int)signlen) goto error; // Check the PKCS7 signature, but not the certificate chain. r = PKCS7_verify(message, NULL, NULL, NULL, out, PKCS7_NOVERIFY); if (r == 0) goto error; // If data block contains less than 32 bytes, fail. size = BIO_get_mem_data(out, &data2); if (size <= UTIL_HASHSIZE) goto error; // Copy the data block *data = (char*)malloc(size + 1); if (*data == NULL) goto error; memcpy(*data, data2, size); (*data)[size] = 0; // Get the certificate signer st = PKCS7_get0_signers(message, NULL, PKCS7_NOVERIFY); cert->x509 = X509_dup(sk_X509_value(st, 0)); sk_X509_free(st); // Get a full certificate hash of the signer r = UTIL_HASHSIZE; X509_digest(cert->x509, EVP_sha256(), (unsigned char*)hash, &r); // Check certificate hash with first 32 bytes of data. if (memcmp(hash, *data, UTIL_HASHSIZE) != 0) goto error; // Approved, cleanup and return. BIO_free(out); PKCS7_free(message); return size; error: if (out != NULL) BIO_free(out); if (message != NULL) PKCS7_free(message); if (*data != NULL) free(*data); if (cert->x509 != NULL) { X509_free(cert->x509); cert->x509 = NULL; } return 0; }
static int check_signer_name(CMS_ContentInfo *cms, const char *name) { STACK_OF(CMS_SignerInfo) *infos = CMS_get0_SignerInfos(cms); STACK_OF(X509) *crts; int i, ret = 1; if ((name == NULL) || (name[0] == '\0')) return 0; crts = CMS_get1_certs(cms); for (i = 0; i < sk_CMS_SignerInfo_num(infos); ++i) { CMS_SignerInfo *si = sk_CMS_SignerInfo_value(infos, i); int j; for (j = 0; j < sk_X509_num(crts); ++j) { X509 *crt = sk_X509_value(crts, j); if (CMS_SignerInfo_cert_cmp(si, crt) == 0) { ret = check_common_name( X509_get_subject_name(crt), name); } } } sk_X509_pop_free(crts, X509_free); return ret; }
static VALUE ossl_x509stctx_get_chain(VALUE self) { X509_STORE_CTX *ctx; STACK_OF(X509) *chain; X509 *x509; int i, num; VALUE ary; GetX509StCtx(self, ctx); if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){ return Qnil; } if((num = sk_X509_num(chain)) < 0){ OSSL_Debug("certs in chain < 0???"); return rb_ary_new(); } ary = rb_ary_new2(num); for(i = 0; i < num; i++) { x509 = sk_X509_value(chain, i); rb_ary_push(ary, ossl_x509_new(x509)); } return ary; }
static int ssl_check_certificate (CONNECTION *conn, sslsockdata *data) { int i, preauthrc, chain_len; STACK_OF(X509) *chain; X509 *cert; if ((preauthrc = ssl_check_preauth (data->cert, conn->account.host)) > 0) return preauthrc; chain = SSL_get_peer_cert_chain (data->ssl); chain_len = sk_X509_num (chain); /* negative preauthrc means the certificate won't be accepted without * manual override. */ if (preauthrc < 0 || !chain || (chain_len <= 1)) return interactive_check_cert (data->cert, 0, 0); /* check the chain from root to peer. */ for (i = chain_len-1; i >= 0; i--) { cert = sk_X509_value (chain, i); /* if the certificate validates or is manually accepted, then add it to * the trusted set and recheck the peer certificate */ if (ssl_check_preauth (cert, NULL) || interactive_check_cert (cert, i, chain_len)) { ssl_cache_trusted_cert (cert); if (ssl_check_preauth (data->cert, conn->account.host)) return 1; } } return 0; }
static PyObject * ssl_Connection_get_peer_cert_chain(ssl_ConnectionObj *self, PyObject *args) { STACK_OF(X509) *sk; PyObject *chain; crypto_X509Obj *cert; Py_ssize_t i; if (!PyArg_ParseTuple(args, ":get_peer_cert_chain")) { return NULL; } sk = SSL_get_peer_cert_chain(self->ssl); if (sk != NULL) { chain = PyList_New(sk_X509_num(sk)); for (i = 0; i < sk_X509_num(sk); i++) { cert = new_x509(sk_X509_value(sk, i), 1); if (!cert) { /* XXX Untested */ Py_DECREF(chain); return NULL; } CRYPTO_add(&cert->x509->references, 1, CRYPTO_LOCK_X509); PyList_SET_ITEM(chain, i, (PyObject *)cert); } return chain; } else { Py_INCREF(Py_None); return Py_None; } }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { int i, j; /* * Preverify checks the platform's certificate store; don't * allow any chain that doesn't already validate according to * that. */ if (!preverify_ok) return 0; /* check each certificate in the chain against our built-in pinlist. */ STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(ctx); if (!chain) die("No certificate chain available"); bool found = false; for (i=0; i < sk_X509_num(chain); i++) { _cleanup_free_ char *spki_hash = NULL; spki_hash = hash_subject_pubkey_info(sk_X509_value(chain, i)); if (!spki_hash) continue; for (j=0; j < (int) ARRAY_SIZE(PK_PINS); j++) { if (strcmp(PK_PINS[j], spki_hash) == 0) { found = true; break; } } } return found; }
// success of certificates extraction bool pemData(X509_STORE_CTX* ctx, ListHashSet<String>& certificates) { bool ok = true; STACK_OF(X509)* certs = X509_STORE_CTX_get1_chain(ctx); for (int i = 0; i < sk_X509_num(certs); i++) { X509* uCert = sk_X509_value(certs, i); BIO* bio = BIO_new(BIO_s_mem()); int res = PEM_write_bio_X509(bio, uCert); if (!res) { ok = false; BIO_free(bio); break; } unsigned char* certificateData; long length = BIO_get_mem_data(bio, &certificateData); if (length < 0) { ok = false; BIO_free(bio); break; } certificateData[length] = '\0'; String certificate = certificateData; certificates.add(certificate); BIO_free(bio); } sk_X509_pop_free(certs, X509_free); return ok; }
static int verify_certificate_chain(X509_STORE_CTX * x509_ctx, void * ignored) { qeo_platform_custom_certificate_validator custom_cert_validator_cb = qeo_platform_get_custom_certificate_validator(); qeo_der_certificate certificate_chain[10]; BIO* bios[10]; int rc = 0; /** We need access to unchecked chain of certificates * No obvious API is found to get a hold of it. The API's available to get certificates * expect to do the verification first and only then you can get the chain. * As we want to do the validation ourselves, we just pull them out the struct to get * the untrusted chain. */ STACK_OF(X509) *sk = x509_ctx->untrusted; if (sk) { //Lets check the stack. qeo_util_retcode_t retcode = QEO_UTIL_EFAIL; int certs = sk_X509_num(sk); int i; if (certs > 10) { //to many certificates; //there is also a limit of 10 in openssl for the maximum certificate chain length. We should not hit this; Still better safe then sorry. return 0; } memset(bios, 0, sizeof(BIO*) * 10); for (i = 0; i < certs ; i++) { int result; X509* cert = sk_X509_value(sk, i); //create a memory BIO BIO *mem = BIO_new(BIO_s_mem()); if (NULL == mem) { goto out; //failed to create BIO } bios[i] = mem; //write to bio int i2d_X509_bio(BIO *bp, X509 *x); result = i2d_X509_bio(mem, cert); if (result < 0) { qeo_log_e("Failed to write certificate data to mem bio %d\n", result); goto out; } // add to array certificate_chain[i].size = BIO_get_mem_data(mem, &certificate_chain[i].cert_data); } //call the callback retcode = custom_cert_validator_cb(certificate_chain, certs); if (retcode == QEO_UTIL_OK) { rc = 1; } else { qeo_log_e("Custom certificate verification callback returned %d - Treating this as a verification error\n", retcode); } out: //free memory for (i = 0; i < certs ; i++) { if (bios[i]) BIO_vfree(bios[i]); //we take the void version; not much we can do if the free fails } } return rc; }
/** * Adds all subjects in a PKCS12 files and notifies the frontend of them. */ static TokenError _backend_addFile(Backend *backend, const char *data, size_t length, void *tag) { SharedPKCS12 *p12 = pkcs12_parse(data, length); if (!p12) return TokenError_BadFile; STACK_OF(X509) *certList = pkcs12_listCerts(p12->data); if (!certList) return TokenError_Unknown; int certCount = sk_X509_num(certList); for (int i = 0; i < certCount; i++) { X509 *x = sk_X509_value(certList, i); if (!certutil_hasKeyUsage(x, backend->notifier->keyUsage)) goto dontAddCert; X509_NAME *id = X509_get_subject_name(x); if (!certutil_matchSubjectFilter(backend->notifier->subjectFilter, id)) goto dontAddCert; PKCS12Token *token = createToken(backend, p12, id, tag); if (token) { backend->notifier->notifyFunction((Token*)token, TokenChange_Added); continue; } dontAddCert: X509_free(x); } pkcs12_release(p12); return TokenError_Success; }
/* * call-seq: * ssl.peer_cert_chain => [cert, ...] or nil */ static VALUE ossl_ssl_get_peer_cert_chain(VALUE self) { SSL *ssl; STACK_OF(X509) *chain; X509 *cert; VALUE ary; int i, num; Data_Get_Struct(self, SSL, ssl); if(!ssl){ rb_warning("SSL session is not started yet."); return Qnil; } chain = SSL_get_peer_cert_chain(ssl); if(!chain) return Qnil; num = sk_X509_num(chain); ary = rb_ary_new2(num); for (i = 0; i < num; i++){ cert = sk_X509_value(chain, i); rb_ary_push(ary, ossl_x509_new(cert)); } return ary; }
Settings::KeyPair CertWizard::importCert(QByteArray data, const QString &pw) { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; PKCS12 *pkcs = NULL; BIO *mem = NULL; STACK_OF(X509) *certs = NULL; Settings::KeyPair kp; int ret = 0; mem = BIO_new_mem_buf(data.data(), data.size()); Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE)); pkcs = d2i_PKCS12_bio(mem, NULL); if (pkcs) { ret = PKCS12_parse(pkcs, NULL, &pkey, &x509, &certs); if (pkcs && !pkey && !x509 && ! pw.isEmpty()) { if (certs) { if (ret) sk_X509_free(certs); certs = NULL; } ret = PKCS12_parse(pkcs, pw.toUtf8().constData(), &pkey, &x509, &certs); } if (pkey && x509 && X509_check_private_key(x509, pkey)) { unsigned char *dptr; QByteArray key, crt; key.resize(i2d_PrivateKey(pkey, NULL)); dptr=reinterpret_cast<unsigned char *>(key.data()); i2d_PrivateKey(pkey, &dptr); crt.resize(i2d_X509(x509, NULL)); dptr=reinterpret_cast<unsigned char *>(crt.data()); i2d_X509(x509, &dptr); QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der); QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der); QList<QSslCertificate> qlCerts; qlCerts << qscCert; if (certs) { for (int i=0;i<sk_X509_num(certs);++i) { X509 *c = sk_X509_value(certs, i); crt.resize(i2d_X509(c, NULL)); dptr=reinterpret_cast<unsigned char *>(crt.data()); i2d_X509(c, &dptr); QSslCertificate cert = QSslCertificate(crt, QSsl::Der); qlCerts << cert; } } bool valid = ! qskKey.isNull(); foreach(const QSslCertificate &cert, qlCerts) valid = valid && ! cert.isNull(); if (valid) kp = Settings::KeyPair(qlCerts, qskKey); } }
/* Open the inner, decrypted PKCS7 and try to write cert. */ void write_other_cert(struct scep *s) { PKCS7 *p7; STACK_OF(X509) *certs; X509 *cert = NULL; FILE *fp; int i; othercert = NULL; /* Get certs */ p7 = s->reply_p7; certs = p7->d.sign->cert; /* Find cert */ for (i = 0; i < sk_X509_num(certs); i++) { char buffer[1024]; cert = sk_X509_value(certs, i); if (v_flag) { printf("%s: found certificate with\n" " subject: %s\n", pname, X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer))); printf(" issuer: %s\n", X509_NAME_oneline(X509_get_issuer_name(cert), buffer, sizeof(buffer))); } /* The serial has to match to requested one */ if (!ASN1_INTEGER_cmp(X509_get_serialNumber(cert), s->ias_getcert->serial)) { othercert = cert; break; } } if (othercert == NULL) { fprintf(stderr, "%s: cannot find certificate\n", pname); exit (SCEP_PKISTATUS_FILE); } /* Write PEM-formatted file: */ if (!(fp = fopen(w_char, "w"))) { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); } if (v_flag) printf("%s: writing cert\n", pname); if (d_flag) PEM_write_X509(stdout, othercert); if (PEM_write_X509(fp, othercert) != 1) { fprintf(stderr, "%s: error while writing certificate " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } printf("%s: certificate written as %s\n", pname, w_char); (void)fclose(fp); }
int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags) { int i; long l; OCSP_CERTID* cid = NULL; OCSP_ONEREQ *one = NULL; OCSP_REQINFO *inf = o->tbsRequest; OCSP_SIGNATURE *sig = o->optionalSignature; if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err; l=ASN1_INTEGER_get(inf->version); if (BIO_printf(bp," Version: %lu (0x%lx)",l+1,l) <= 0) goto err; if (inf->requestorName != NULL) { if (BIO_write(bp,"\n Requestor Name: ",21) <= 0) goto err; GENERAL_NAME_print(bp, inf->requestorName); } if (BIO_write(bp,"\n Requestor List:\n",21) <= 0) goto err; for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { one = sk_OCSP_ONEREQ_value(inf->requestList, i); cid = one->reqCert; ocsp_certid_print(bp, cid, 8); if (!X509V3_extensions_print(bp, "Request Single Extensions", one->singleRequestExtensions, flags, 8)) goto err; } if (!X509V3_extensions_print(bp, "Request Extensions", inf->requestExtensions, flags, 4)) goto err; if (sig) { X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); for (i=0; i<sk_X509_num(sig->certs); i++) { X509_print(bp, sk_X509_value(sig->certs,i)); PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i)); } } return 1; err: return 0; }
/* * Returns: 0 if successfully matching certificate to TLSA record bytes * -1 if there was no match */ int ca_constraint(const SSL *con, const X509 *tlsa_cert, int usage) { STACK_OF(X509) *cert_chain = NULL; cert_chain = SSL_get_peer_cert_chain(con); BIO_printf(b_err, "DANE ca_constraint() chain of %d length\n", sk_X509_num(cert_chain)); int ret_val; ret_val = 0; if (cert_chain != NULL) { int i; for (i = 0; i < sk_X509_num(cert_chain); i++) { BIO_printf(b_err, "DANE ca_constraint() cert %d of %d.\n", i, sk_X509_num(cert_chain)); /* BIO_printf(b_err, "DANE CXN Certificate\n"); PEM_write_bio_X509(b_err, sk_X509_value(cert_chain, i)); BIO_printf(b_err, "DANE TLSA Certificate\n"); PEM_write_bio_X509(b_err, tlsa_cert); */ if (X509_cmp(tlsa_cert, sk_X509_value(cert_chain, i)) < 0) { ret_val = -1; BIO_printf(b_err, "DANE ca_constraint() certificates didn't match\n"); } else { BIO_printf(b_err, "DANE ca_constraint() certificates matches\n"); if (usage == 0) return 0; /* For this to be a trust anchor, the following characteristics applies: * 1. Issuer name is the same as Subject name * 2. Either or both * a) the Key Usage field is set to keyCertSign (KU_KEY_CERT_SIGN) * b) the basicConstraints field has the attribute cA set to True (EXFLAG_CA) */ X509_NAME *issuer_name, *subject_name; issuer_name = X509_get_issuer_name(tlsa_cert); subject_name = X509_get_subject_name(tlsa_cert); if (X509_name_cmp(issuer_name, subject_name) == 0) { BIO_printf(b_err, "DANE issuer == subject\n"); if (tlsa_cert->ex_flags & EXFLAG_CA) { BIO_printf(b_err, "DANE ca_constraint() EXFLAG_CA set\n"); return 0; } /* Left unimplemented since I don't have a CA certificate to work with.*/ int ext_count, j; ext_count = X509_get_ext_count(tlsa_cert); BIO_printf(b_err, "DANE ca_constraint() %d certificate extensions\n"); } else { return 0; } } } } return ret_val; }
pki_x509 *pki_pkcs7::getCert(int x) { pki_x509 *cert; cert = new pki_x509(X509_dup(sk_X509_value(getCertStack(), x))); openssl_error(); cert->autoIntName(); cert->pkiSource = imported; return cert; }
int GTPublicationsFile_getSigningCert( const GTPublicationsFile *publications_file, unsigned char **cert_der, size_t *cert_der_length) { int res = GT_UNKNOWN_ERROR; unsigned char *i2dp; unsigned char *tmp_der = NULL; int tmp_der_len; X509 *signing_cert = NULL; STACK_OF(X509) *certs = NULL; if (publications_file == NULL || publications_file->signature == NULL || cert_der == NULL || cert_der_length == NULL) { res = GT_INVALID_ARGUMENT; goto cleanup; } certs = PKCS7_get0_signers(publications_file->signature, NULL, 0); if (certs == NULL) { res = GT_INVALID_FORMAT; goto cleanup; } if (sk_X509_num(certs) != 1) { res = GT_INVALID_FORMAT; goto cleanup; } signing_cert = sk_X509_value(certs, 0); tmp_der_len = i2d_X509(signing_cert, NULL); if (tmp_der_len < 0) { res = GT_CRYPTO_FAILURE; goto cleanup; } tmp_der = GT_malloc(tmp_der_len); if (tmp_der == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } i2dp = tmp_der; i2d_X509(signing_cert, &i2dp); *cert_der = tmp_der; tmp_der = NULL; *cert_der_length = tmp_der_len; res = GT_OK; cleanup: GT_free(tmp_der); sk_X509_free(certs); return res; }
/* find the issuer certificate without lookups */ NOEXPORT X509 *get_current_issuer(X509_STORE_CTX *callback_ctx) { STACK_OF(X509) *chain; int depth; chain=X509_STORE_CTX_get_chain(callback_ctx); depth=X509_STORE_CTX_get_error_depth(callback_ctx); if(depth<sk_X509_num(chain)-1) /* not the root CA cert */ ++depth; /* index of the issuer cert */ return sk_X509_value(chain, depth); }
/** This function will return the leaf signer certificate in a chain. This is required because certificate chains are not guaranteed to have the certificates in the order that they were issued. A typical certificate chain looks like this: ---------------------------- | Root | ---------------------------- ^ | ---------------------------- | Policy CA | <-- Typical Trust Anchor. ---------------------------- ^ | ---------------------------- | Issuing CA | ---------------------------- ^ | ----------------------------- / End-Entity (leaf) signer / <-- Bottom certificate. ----------------------------- EKU: "1.3.6.1.4.1.311.76.9.21.1" (Firmware Signing) @param[in] CertChain Certificate chain. @param[out] SignerCert Last certificate in the chain. For PKCS7 signatures, this will be the end-entity (leaf) signer cert. @retval EFI_SUCCESS The required EKUs were found in the signature. @retval EFI_INVALID_PARAMETER A parameter was invalid. @retval EFI_NOT_FOUND The number of signers found was not 1. **/ EFI_STATUS GetSignerCertificate ( IN CONST PKCS7 *CertChain, OUT X509 **SignerCert ) { EFI_STATUS Status; STACK_OF(X509) *Signers; INT32 NumberSigners; Status = EFI_SUCCESS; Signers = NULL; NumberSigners = 0; if (CertChain == NULL || SignerCert == NULL) { Status = EFI_INVALID_PARAMETER; goto Exit; } // // Get the signers from the chain. // Signers = PKCS7_get0_signers ((PKCS7*) CertChain, NULL, PKCS7_BINARY); if (Signers == NULL) { // // Fail to get signers form PKCS7 // Status = EFI_INVALID_PARAMETER; goto Exit; } // // There should only be one signer in the PKCS7 stack. // NumberSigners = sk_X509_num (Signers); if (NumberSigners != 1) { // // The number of singers should have been 1 // Status = EFI_NOT_FOUND; goto Exit; } *SignerCert = sk_X509_value (Signers, 0); Exit: // // Release Resources // if (Signers) { sk_X509_free (Signers); } return Status; }
static int check_certificate_by_signer (X509 *peercert) { X509_STORE_CTX *xsc; X509_STORE *ctx; int pass = 0, i; ctx = X509_STORE_new (); if (ctx == NULL) return 0; if (option (OPTSSLSYSTEMCERTS)) { if (X509_STORE_set_default_paths (ctx)) pass++; else dprint (2, (debugfile, "X509_STORE_set_default_paths failed\n")); } if (X509_STORE_load_locations (ctx, SslCertFile, NULL)) pass++; else dprint (2, (debugfile, "X509_STORE_load_locations failed\n")); for (i = 0; i < sk_X509_num (SslSessionCerts); i++) pass += (X509_STORE_add_cert (ctx, sk_X509_value (SslSessionCerts, i)) != 0); if (pass == 0) { /* nothing to do */ X509_STORE_free (ctx); return 0; } xsc = X509_STORE_CTX_new(); if (xsc == NULL) return 0; X509_STORE_CTX_init (xsc, ctx, peercert, SslSessionCerts); pass = (X509_verify_cert (xsc) > 0); #ifdef DEBUG if (! pass) { char buf[SHORT_STRING]; int err; err = X509_STORE_CTX_get_error (xsc); snprintf (buf, sizeof (buf), "%s (%d)", X509_verify_cert_error_string(err), err); dprint (2, (debugfile, "X509_verify_cert: %s\n", buf)); dprint (2, (debugfile, " [%s]\n", peercert->name)); } #endif X509_STORE_CTX_free (xsc); X509_STORE_free (ctx); return pass; }
bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName) { X509_STORE_CTX *storeContext = verifyCtx.native_handle(); int currentDepth = X509_STORE_CTX_get_error_depth(storeContext); if (currentDepth != 0) { return true; } STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext); const int numCerts = sk_X509_num(certStack); if (numCerts < 0) { return false; } std::vector<std::string> certChain; certChain.reserve(numCerts); for (int i = 0; i < numCerts; ++i) { X509 *cert = sk_X509_value(certStack, i); // Encode into DER format into raw memory. int len = i2d_X509(cert, nullptr); if (len < 0) { return false; } std::string certData; certData.resize(len); unsigned char * buffer = reinterpret_cast<unsigned char *>(&certData[0]); len = i2d_X509(cert, &buffer); if (len < 0) { return false; } certChain.push_back(std::move(certData)); } auto verify_result = verify_X509_cert_chain(certChain, hostName); // The Windows Crypto APIs don't do host name checks, use Boost's implementation. #if defined(_WIN32) if (verify_result) { boost::asio::ssl::rfc2818_verification rfc2818(hostName); verify_result = rfc2818(verify_result, verifyCtx); } #endif return verify_result; }
// VerifyChain verifies the certificate chain in chain // according to the verification options given as opts. bool X509VerifierPrivate::VerifyChain(std::vector<X509Certificate> chain, const X509VerifierOptions &opts) { bool status = false; X509_STORE_CTX *ctx = X509_STORE_CTX_new(); STACK_OF(X509) *untrusted = sk_X509_new_null(); // Ensure that we have a chain to check on. if (chain.empty()) { goto out; } // If we've been passed a DNS name in opts, // we should check whether the leaf certificate // matches that before doing the more expensive // checks. if (!opts.dns_name.empty()) { if (!X509HostnameVerifier::VerifyHostname(chain.at(0), opts.dns_name)) { std::cerr << "X509VerifierPrivate - hostname verification failed" << std::endl; goto out; } } // Extract our chain into the format that OpenSSL // expects for verification. for (X509Certificate &cert : chain) { X509 *cur = cert.dptr_->AsOpenSSLX509(); sk_X509_push(untrusted, cur); } // Set up the X509_STORE_CTX to verify according to opts. X509_STORE_CTX_init(ctx, store_, sk_X509_value(untrusted, 0), untrusted); // If a time is not specified in opts, use the current system time. if (opts.time == 0) { X509_STORE_CTX_set_time(ctx, 0, std::time(nullptr)); } else { X509_STORE_CTX_set_time(ctx, 0, opts.time); } // If a dns_name is specified in opts, use the SSL server policy. if (!opts.dns_name.empty()) { X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SSL_SERVER); X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER); } if (X509_verify_cert(ctx) == 1) { status = true; } else { std::cerr << "X509VerifierPrivate - verification error: " << X509_verify_cert_error_string(ctx->error) << std::endl; } out: sk_X509_pop_free(untrusted, X509_free); X509_STORE_CTX_free(ctx); return status; }