static int cert_check(CLI *c, X509_STORE_CTX *callback_ctx, int preverify_ok) { X509_OBJECT obj; ASN1_BIT_STRING *local_key, *peer_key; if(c->opt->verify_level==SSL_VERIFY_NONE) { s_log(LOG_INFO, "CERT: Verification not enabled"); return 1; /* accept connection */ } if(!preverify_ok) { /* remote site specified a certificate, but it's not correct */ s_log(LOG_WARNING, "CERT: Verification error: %s", X509_verify_cert_error_string(callback_ctx->error)); return 0; /* reject connection */ } if(c->opt->verify_use_only_my && callback_ctx->error_depth==0) { if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509, X509_get_subject_name(callback_ctx->current_cert), &obj)!=1) { s_log(LOG_WARNING, "CERT: Certificate not found in local repository"); return 0; /* reject connection */ } peer_key=X509_get0_pubkey_bitstr(callback_ctx->current_cert); local_key=X509_get0_pubkey_bitstr(obj.data.x509); if(!peer_key || !local_key || peer_key->length!=local_key->length || memcmp(peer_key->data, local_key->data, local_key->length)) { s_log(LOG_WARNING, "CERT: Public keys do not match"); return 0; /* reject connection */ } } return 1; /* accept connection */ }
char *tls_pkey_fprint(X509 *peercert, const char *mdalg) { if (var_tls_bc_pkey_fprint) { const char *myname = "tls_pkey_fprint"; ASN1_BIT_STRING *key; char *result; key = X509_get0_pubkey_bitstr(peercert); if (key == 0) msg_fatal("%s: error extracting legacy public-key fingerprint: %m", myname); result = tls_data_fprint((char *) key->data, key->length, mdalg); return (result); } else { int len; char *buf; char *buf2; char *result; len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL); buf2 = buf = mymalloc(len); i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), (unsigned char **) &buf2); if (buf2 - buf != len) msg_panic("i2d_X509_PUBKEY invalid result length"); result = tls_data_fprint(buf, len, mdalg); myfree(buf); return (result); } }
NOEXPORT int compare_pubkeys(X509 *c1, X509 *c2) { #if OPENSSL_VERSION_NUMBER>=0x0090700fL ASN1_BIT_STRING *k1=X509_get0_pubkey_bitstr(c1); ASN1_BIT_STRING *k2=X509_get0_pubkey_bitstr(c2); if(!k1 || !k2 || k1->length!=k2->length || k1->length<0 || safe_memcmp(k1->data, k2->data, (size_t)k1->length)) { s_log(LOG_DEBUG, "CERT: Public keys do not match"); return 0; /* reject */ } #else (void)c1; /* skip warning about unused parameter */ (void)c2; /* skip warning about unused parameter */ #endif s_log(LOG_INFO, "CERT: Locally installed certificate matched"); return 1; /* accept */ }
OCSP_CERTID *OCSP_cert_to_id (const EVP_MD * dgst, X509 * subject, X509 * issuer) { X509_NAME *iname; ASN1_INTEGER *serial; ASN1_BIT_STRING *ikey; #ifndef OPENSSL_NO_SHA1 if (!dgst) dgst = EVP_sha1 (); #endif if (subject) { iname = X509_get_issuer_name (subject); serial = X509_get_serialNumber (subject); } else { iname = X509_get_subject_name (issuer); serial = NULL; } ikey = X509_get0_pubkey_bitstr (issuer); return OCSP_cert_id_new (dgst, iname, ikey, serial); }
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { ASN1_BIT_STRING *key; key = X509_get0_pubkey_bitstr(data); if(!key) return 0; return EVP_Digest(key->data, key->length, md, len, type, NULL); }
static int cert_check(CLI *c, X509_STORE_CTX *callback_ctx, int preverify_ok) { X509_OBJECT obj; #if OPENSSL_VERSION_NUMBER>=0x0090700fL ASN1_BIT_STRING *local_key, *peer_key; #endif X509 *cert; int depth; if(c->opt->verify_level<1) { s_log(LOG_INFO, "CERT: Verification not enabled"); return 1; /* accept connection */ } cert=X509_STORE_CTX_get_current_cert(callback_ctx); depth=X509_STORE_CTX_get_error_depth(callback_ctx); if(!preverify_ok) { /* remote site specified a certificate, but it's not correct */ if(c->opt->verify_level>=4 && depth>0) { s_log(LOG_INFO, "CERT: Invalid CA certificate ignored"); return 1; /* accept connection */ } else { s_log(LOG_WARNING, "CERT: Verification error: %s", X509_verify_cert_error_string( X509_STORE_CTX_get_error(callback_ctx))); return 0; /* reject connection */ } } if(c->opt->verify_level>=3 && depth==0) { if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509, X509_get_subject_name(cert), &obj)!=1) { s_log(LOG_WARNING, "CERT: Certificate not found in local repository"); return 0; /* reject connection */ } #if OPENSSL_VERSION_NUMBER>=0x0090700fL peer_key=X509_get0_pubkey_bitstr(cert); local_key=X509_get0_pubkey_bitstr(obj.data.x509); if(!peer_key || !local_key || peer_key->length!=local_key->length || memcmp(peer_key->data, local_key->data, local_key->length)) { s_log(LOG_WARNING, "CERT: Public keys do not match"); return 0; /* reject connection */ } #endif s_log(LOG_INFO, "CERT: Locally installed certificate matched"); } return 1; /* accept connection */ }
static int verify_local_public_key (X509 * crt) { int l; void *p = NULL; if (!cache_pkey) { char *cn, *cn1; char *fn; BIO *cb; X509 *cache_crt; cn = get_cn_from_crt (crt); if (!cn) return (0); cn1 = cn; if (*cn1 == '*') cn1++; if (*cn1 == '.') cn1++; fn = (char *) malloc (strlen (PBC_KEY_DIR) + strlen (cn1) + 16); sprintf (fn, "%s/%s.crt", PBC_KEY_DIR, cn1); cb = BIO_new (BIO_s_file ()); if (BIO_read_filename (cb, fn) > 0) { cache_crt = PEM_read_bio_X509 (cb, NULL, NULL, NULL); if (cache_crt) cache_pkey = X509_get0_pubkey_bitstr (cache_crt); } BIO_free (cb); free (cn); free (fn); } if (cache_pkey) { ASN1_BIT_STRING *nkey; nkey = X509_get0_pubkey_bitstr (crt); if (nkey && (nkey->length == cache_pkey->length) && (memcmp (nkey->data, cache_pkey->data, nkey->length) == 0)) return (1); } return (0); }
int X509_ocspid_print(BIO *bp, X509 *x) { unsigned char *der = NULL; unsigned char *dertmp; int derlen; int i; unsigned char SHA1md[SHA_DIGEST_LENGTH]; ASN1_BIT_STRING *keybstr; X509_NAME *subj; /* * display the hash of the subject as it would appear in OCSP requests */ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) goto err; subj = X509_get_subject_name(x); derlen = i2d_X509_NAME(subj, NULL); if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL) goto err; i2d_X509_NAME(subj, &dertmp); if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) goto err; for (i = 0; i < SHA_DIGEST_LENGTH; i++) { if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) goto err; } OPENSSL_free(der); der = NULL; /* * display the hash of the public key as it would appear in OCSP requests */ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) goto err; keybstr = X509_get0_pubkey_bitstr(x); if (keybstr == NULL) goto err; if (!EVP_Digest(ASN1_STRING_get0_data(keybstr), ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(), NULL)) goto err; for (i = 0; i < SHA_DIGEST_LENGTH; i++) { if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) goto err; } BIO_printf(bp, "\n"); return 1; err: OPENSSL_free(der); return 0; }
// Create a filename, based on the actual data for a certificate char *GenerateFileName(unsigned int version_num, const byte *dercert_data, size_t dercert_len, BOOL with_pub_key, const DEFCERT_keyid_item *item) { if(dercert_data == NULL) return NULL; char *ret = NULL; // Work buffer, large enough to hold the largest hash in asciiform in _XXXX form char *buffer = new char[((EVP_MAX_MD_SIZE+1)/2)*5+1]; unsigned char *name = NULL; X509 *cert = NULL; if(buffer == NULL) return NULL; do { // Get the certificate const unsigned char *data = dercert_data; X509 *cert = d2i_X509(NULL, &data, dercert_len); if(cert == NULL) break; // buffer for name hash unsigned char name_hash[EVP_MAX_MD_SIZE+1]; /* ARRAY OK 2009-06-11 yngve */ EVP_MD_CTX hash; // extract name int len = i2d_X509_NAME(X509_get_subject_name(cert), &name); if(name == NULL) break; // digest it EVP_DigestInit(&hash, EVP_sha256()); EVP_DigestUpdate(&hash, name, len); if(with_pub_key) { // and if requested the public key ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(cert); if(key) EVP_DigestUpdate(&hash, key->data, key->length); } // and a key id if(item && item->keyid) EVP_DigestUpdate(&hash, item->keyid, item->keyid_len); // version number is first part of name name_hash[0] = version_num; unsigned int md_len = 0; // then the digest result EVP_DigestFinal(&hash, name_hash+1, &md_len); // Hexify the result char *id_string = buffer; int id_len = md_len+1, i =0; // first, version number if(version_num) { sprintf(id_string, "%.2X", name_hash[i]); id_string+=2; } // then each pair of bytes for(i++ ;i<id_len; i+=2, id_string+=5) sprintf(id_string, (i+2 < id_len ? "%.2X%.2X_" : "%.2X%.2X"), name_hash[i], name_hash[i+1]); char *short_name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); if(short_name) { printf("%s\n %s: %s\n %s\n", short_name, (with_pub_key ? "TRUE" : "FALSE"), (item == NULL ? "No dep" : "dep"), buffer); OPENSSL_free(short_name); } // Return in buffe ret = buffer; }while(0); if(name) OPENSSL_free(name); name = NULL; if(cert) X509_free(cert); cert = NULL; // If no return free buffer if(ret == NULL) delete [] buffer; buffer = NULL; return ret; }
const void * PKI_X509_CERT_get_data(const PKI_X509_CERT * x, PKI_X509_DATA type) { const void *ret = NULL; LIBPKI_X509_CERT *tmp_x = NULL; if (!x || !x->value) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); } tmp_x = x->value; switch (type) { case PKI_X509_DATA_VERSION: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->cert_info) ret = (tmp_x)->cert_info->version; #else ret = (tmp_x)->cert_info.version; #endif break; case PKI_X509_DATA_SERIAL: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->cert_info) ret = tmp_x->cert_info->serialNumber; #else ret = &((tmp_x)->cert_info.serialNumber); #endif // ret = X509_get_serialNumber ( (X509 *) x->value ); break; case PKI_X509_DATA_SUBJECT: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->cert_info) ret = tmp_x->cert_info->subject; #else ret = tmp_x->cert_info.subject; #endif // ret = X509_get_subject_name( (X509 *) x->value ); break; case PKI_X509_DATA_ISSUER: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->cert_info) ret = tmp_x->cert_info->issuer; #else ret = tmp_x->cert_info.issuer; #endif // ret = X509_get_issuer_name( (X509 *) x->value ); break; case PKI_X509_DATA_NOTBEFORE: #if OPENSSL_VERSION_NUMBER < 0x1010000fL ret = tmp_x->cert_info->validity->notBefore; #else ret = X509_get0_notBefore((X509 *)tmp_x); #endif break; case PKI_X509_DATA_NOTAFTER: #if OPENSSL_VERSION_NUMBER < 0x1010000fL ret = tmp_x->cert_info->validity->notAfter; #else ret = X509_get0_notAfter((X509 *)tmp_x); #endif break; case PKI_X509_DATA_KEYPAIR_VALUE: case PKI_X509_DATA_PUBKEY: ret = X509_get_pubkey((X509 *)tmp_x); break; case PKI_X509_DATA_PUBKEY_BITSTRING: ret = X509_get0_pubkey_bitstr((X509 *)tmp_x); break; case PKI_X509_DATA_SIGNATURE: #if OPENSSL_VERSION_NUMBER < 0x1010000fL ret = (tmp_x)->signature; #else ret = &(tmp_x)->signature; #endif break; // Signature Algorithm within the certInfo structure case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->cert_info && tmp_x->cert_info->signature) ret = tmp_x->cert_info->signature; #else ret = X509_get0_tbs_sigalg((const X509 *)x->value); #endif break; case PKI_X509_DATA_SIGNATURE_ALG2: #if OPENSSL_VERSION_NUMBER < 0x1010000fL if (tmp_x->sig_alg) ret = tmp_x->sig_alg; #else ret = &tmp_x->sig_alg; #endif break; case PKI_X509_DATA_KEYSIZE: case PKI_X509_DATA_CERT_TYPE: PKI_ERROR(PKI_ERR_PARAM_TYPE, "Deprecated Cert Datatype"); break; /* case PKI_X509_DATA_KEYSIZE: tmp_int = PKI_Malloc ( sizeof( int )); *tmp_int = EVP_PKEY_size(X509_get_pubkey((X509 *)x->value)); ret = tmp_int; break; case PKI_X509_DATA_CERT_TYPE: tmp_int = PKI_Malloc ( sizeof ( int )); *tmp_int = PKI_X509_CERT_get_type( x ); break; */ case PKI_X509_DATA_EXTENSIONS: #if OPENSSL_VERSION_NUMBER < 0x1010000fL ret = tmp_x->cert_info->extensions; #else ret = tmp_x->cert_info.extensions; #endif break; default: /* Not Recognized/Supported DATATYPE */ return (NULL); } return (ret); }
static int openssl_ocsp_request_new(lua_State*L) { OCSP_REQUEST *req = NULL; if (lua_isstring(L, 1)) { BIO* bio = load_bio_object(L, 1); req = d2i_OCSP_REQUEST_bio(bio, NULL); /* if (!req) { BIO_reset(bio); req = PEM_read_bio_OCSP_REQUEST(bio, NULL, NULL); } */ BIO_free(bio); } else { X509 *issuer = CHECK_OBJECT(1, X509, "openssl.x509"); X509_NAME *iname = X509_get_subject_name(issuer); ASN1_BIT_STRING *ikey = X509_get0_pubkey_bitstr(issuer); OCSP_CERTID *id = NULL; OCSP_ONEREQ *one; char buf[1024]; int nonce = lua_gettop(L) > 2 ? auxiliar_checkboolean(L, 3) : 0; req = OCSP_REQUEST_new(); if (lua_istable(L, 2)) { int len = lua_rawlen(L, 2); int i; for (i = 1; i <= len; i++) { lua_rawgeti(L, 2, i); if (auxiliar_isclass(L, "openssl.x509", -1)) { X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509"); id = OCSP_cert_to_id(NULL, cert, issuer); one = OCSP_request_add0_id(req, id); } else { size_t len; char *serial = (char *)luaL_checklstring(L, -1, &len); ASN1_INTEGER *sno = ASN1_INTEGER_new(); BIO* bio = BIO_new(BIO_s_mem()); BIO_write(bio, serial, len); if (a2i_ASN1_INTEGER(bio, sno, buf, 1024) == 1) { id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); one = OCSP_request_add0_id(req, id); }; ASN1_INTEGER_free(sno); BIO_free(bio); } lua_pop(L, 1); } } else if (auxiliar_isclass(L, "openssl.x509", 2)) { X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509"); id = OCSP_cert_to_id(NULL, cert, issuer); one = OCSP_request_add0_id(req, id); } else { ASN1_INTEGER *sno = ASN1_INTEGER_new(); BIO* bio = load_bio_object(L, 2); if (a2i_ASN1_INTEGER(bio, sno, buf, 1024) == 1) { id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); one = OCSP_request_add0_id(req, id); }; ASN1_INTEGER_free(sno); BIO_free(bio); } if (nonce) OCSP_request_add1_nonce(req, NULL, -1); } if(req) { PUSH_OBJECT(req, "openssl.ocsp_request"); }else lua_pushnil(L); return 1; }
void * PKI_X509_CERT_get_data ( PKI_X509_CERT *x, PKI_X509_DATA type ) { void *ret = NULL; PKI_X509_CERT_VALUE *tmp_x = NULL; PKI_MEM *mem = NULL; int *tmp_int = NULL; if( !x || !x->value ) return (NULL); tmp_x = x->value; switch (type) { case PKI_X509_DATA_VERSION: ret = (tmp_x)->cert_info->version; break; case PKI_X509_DATA_SERIAL: ret = X509_get_serialNumber ( (X509 *) x->value ); break; case PKI_X509_DATA_SUBJECT: ret = X509_get_subject_name( (X509 *) x->value ); break; case PKI_X509_DATA_ISSUER: ret = X509_get_issuer_name( (X509 *) x->value ); break; case PKI_X509_DATA_NOTBEFORE: ret = X509_get_notBefore( (X509 *) x->value ); break; case PKI_X509_DATA_NOTAFTER: ret = X509_get_notAfter( (X509 *) x->value ); break; case PKI_X509_DATA_KEYPAIR_VALUE: case PKI_X509_DATA_PUBKEY: ret = X509_get_pubkey( (X509 *) x->value); break; case PKI_X509_DATA_PUBKEY_BITSTRING: ret = X509_get0_pubkey_bitstr( (X509 *) x->value); break; case PKI_X509_DATA_SIGNATURE: ret = (void *) (tmp_x)->signature; break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG1: if (tmp_x->cert_info && tmp_x->cert_info->signature) ret = tmp_x->cert_info->signature; break; case PKI_X509_DATA_SIGNATURE_ALG2: if (tmp_x->sig_alg) ret = tmp_x->sig_alg; break; case PKI_X509_DATA_KEYSIZE: tmp_int = PKI_Malloc ( sizeof( int )); *tmp_int = EVP_PKEY_size( X509_get_pubkey ( (X509 *) x->value )); ret = tmp_int; break; case PKI_X509_DATA_TBS_MEM_ASN1: if((mem = PKI_MEM_new_null()) == NULL ) break; mem->size = (size_t) ASN1_item_i2d ( (void *) tmp_x->cert_info, &(mem->data), &X509_CINF_it ); ret = mem; break; case PKI_X509_DATA_CERT_TYPE: tmp_int = PKI_Malloc ( sizeof ( int )); *tmp_int = PKI_X509_CERT_get_type( x ); break; case PKI_X509_DATA_EXTENSIONS: default: /* Not Recognized/Supported DATATYPE */ return (NULL); } return (ret); }