int X509_CRL_print(BIO *out, X509_CRL *x) { STACK_OF(X509_REVOKED) *rev; X509_REVOKED *r; long l; int i; char *p; BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); if (l < 0 || l == LONG_MAX) goto err; BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); i = OBJ_obj2nid(x->sig_alg->algorithm); if (X509_signature_print(out, x->sig_alg, NULL) == 0) goto err; p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); if (p == NULL) goto err; BIO_printf(out, "%8sIssuer: %s\n", "", p); free(p); BIO_printf(out, "%8sLast Update: ", ""); ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x)); BIO_printf(out, "\n%8sNext Update: ", ""); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x)); else BIO_printf(out, "NONE"); BIO_printf(out, "\n"); X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8); rev = X509_CRL_get_REVOKED(x); if (sk_X509_REVOKED_num(rev) > 0) BIO_printf(out, "Revoked Certificates:\n"); else BIO_printf(out, "No Revoked Certificates.\n"); for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { r = sk_X509_REVOKED_value(rev, i); BIO_printf(out, " Serial Number: "); i2a_ASN1_INTEGER(out, r->serialNumber); BIO_printf(out, "\n Revocation Date: "); ASN1_TIME_print(out, r->revocationDate); BIO_printf(out, "\n"); X509V3_extensions_print(out, "CRL entry extensions", r->extensions, 0, 8); } if (X509_signature_print(out, x->sig_alg, x->signature) == 0) goto err; return 1; err: return 0; }
static LUA_FUNCTION(openssl_crl_get) { X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); int i = 0; X509_REVOKED *revoked = NULL; if (lua_isinteger(L, 2)) { i = lua_tointeger(L, 2); luaL_argcheck(L, (i >= 0 && i < sk_X509_REVOKED_num(crl->crl->revoked)), 2, "Out of range"); revoked = sk_X509_REVOKED_value(crl->crl->revoked, i); } else { ASN1_STRING *sn = CHECK_OBJECT(2, ASN1_STRING, "openssl.asn1_integer"); int cnt = sk_X509_REVOKED_num(crl->crl->revoked); for (i = 0; i < cnt; i++) { X509_REVOKED *rev = sk_X509_REVOKED_value(crl->crl->revoked, i); if (ASN1_STRING_cmp(rev->serialNumber, sn) == 0) { revoked = rev; break; } } } if (revoked) { lua_newtable(L); #if OPENSSL_VERSION_NUMBER > 0x10000000L AUXILIAR_SET(L, -1, "code", revoked->reason, number); AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(revoked->reason), string); #else { int crit = 0; void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); AUXILIAR_SET(L, -1, "code", ASN1_ENUMERATED_get(reason), number); AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string); ASN1_ENUMERATED_free(reason); } #endif PUSH_ASN1_INTEGER(L, revoked->serialNumber); lua_setfield(L, -2, "serialNumber"); PUSH_ASN1_TIME(L, revoked->revocationDate); lua_setfield(L, -2, "revocationDate"); if (crl->crl->extensions) { lua_pushstring(L, "extensions"); openssl_sk_x509_extension_totable(L, crl->crl->extensions); lua_rawset(L, -3); } } else lua_pushnil(L); return 1; }
int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag) { STACK_OF(X509_REVOKED) *rev; X509_REVOKED *r; const X509_ALGOR *sig_alg; const ASN1_BIT_STRING *sig; long l; int i; BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); if (l >= 0 && l <= 1) BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", l + 1, (unsigned long)l); else BIO_printf(out, "%8sVersion unknown (%ld)\n", "", l); X509_CRL_get0_signature(x, &sig, &sig_alg); BIO_puts(out, " "); X509_signature_print(out, sig_alg, NULL); BIO_printf(out, "%8sIssuer: ", ""); X509_NAME_print_ex(out, X509_CRL_get_issuer(x), 0, nmflag); BIO_puts(out, "\n"); BIO_printf(out, "%8sLast Update: ", ""); ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x)); BIO_printf(out, "\n%8sNext Update: ", ""); if (X509_CRL_get0_nextUpdate(x)) ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x)); else BIO_printf(out, "NONE"); BIO_printf(out, "\n"); X509V3_extensions_print(out, "CRL extensions", X509_CRL_get0_extensions(x), 0, 8); rev = X509_CRL_get_REVOKED(x); if (sk_X509_REVOKED_num(rev) > 0) BIO_printf(out, "Revoked Certificates:\n"); else BIO_printf(out, "No Revoked Certificates.\n"); for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { r = sk_X509_REVOKED_value(rev, i); BIO_printf(out, " Serial Number: "); i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r)); BIO_printf(out, "\n Revocation Date: "); ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r)); BIO_printf(out, "\n"); X509V3_extensions_print(out, "CRL entry extensions", X509_REVOKED_get0_extensions(r), 0, 8); } X509_signature_print(out, sig_alg, sig); return 1; }
EXPORT_C int X509_CRL_print(BIO *out, X509_CRL *x) { STACK_OF(X509_REVOKED) *rev; X509_REVOKED *r; long l; int i, n; char *p; BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l); i = OBJ_obj2nid(x->sig_alg->algorithm); BIO_printf(out, "%8sSignature Algorithm: %s\n", "", (i == NID_undef) ? "NONE" : OBJ_nid2ln(i)); p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0); BIO_printf(out,"%8sIssuer: %s\n","",p); OPENSSL_free(p); BIO_printf(out,"%8sLast Update: ",""); ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x)); BIO_printf(out,"\n%8sNext Update: ",""); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x)); else BIO_printf(out,"NONE"); BIO_printf(out,"\n"); n=X509_CRL_get_ext_count(x); X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8); rev = X509_CRL_get_REVOKED(x); if(sk_X509_REVOKED_num(rev) > 0) BIO_printf(out, "Revoked Certificates:\n"); else BIO_printf(out, "No Revoked Certificates.\n"); for(i = 0; i < sk_X509_REVOKED_num(rev); i++) { r = sk_X509_REVOKED_value(rev, i); BIO_printf(out," Serial Number: "); i2a_ASN1_INTEGER(out,r->serialNumber); BIO_printf(out,"\n Revocation Date: "); ASN1_TIME_print(out,r->revocationDate); BIO_printf(out,"\n"); X509V3_extensions_print(out, "CRL entry extensions", r->extensions, 0, 8); } X509_signature_print(out, x->sig_alg, x->signature); return 1; }
STACK_OF(X509_REVOKED) *ocspd_build_crl_entries_list ( CA_LIST_ENTRY *ca, PKI_X509_CRL *crl ) { long rev_num = 0; STACK_OF(X509_REVOKED) *ret = NULL; PKI_X509_CRL_VALUE *crl_val = NULL; if ( !ca || !crl || !crl->value ) { return NULL; } crl_val = crl->value; ret = X509_CRL_get_REVOKED(crl_val); rev_num = sk_X509_REVOKED_num(ret); // if( ocspd_conf->verbose ) PKI_log( PKI_LOG_INFO, "INFO::CRL::%ld Entries [ %s ]", rev_num, ca->ca_id ); ca->crl_list = ret; ca->entries_num = (unsigned long) rev_num; if ((rev_num > -1 ) && (ca->crl_list == NULL)) { PKI_ERROR( PKI_ERR_MEMORY_ALLOC, NULL ); return NULL; } sk_X509_REVOKED_sort(ca->crl_list); return (ca->crl_list); }
int pki_crl::numRev() { if (crl && crl->crl && crl->crl->revoked) return sk_X509_REVOKED_num(crl->crl->revoked); else return 0; }
static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer) { X509_REVOKED rtmp, *rev; int idx; rtmp.serialNumber = *serial; /* * Sort revoked into serial number order if not already sorted. Do this * under a lock to avoid race condition. */ if (!sk_X509_REVOKED_is_sorted(crl->crl.revoked)) { CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); sk_X509_REVOKED_sort(crl->crl.revoked); CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); } idx = sk_X509_REVOKED_find(crl->crl.revoked, &rtmp); if (idx < 0) return 0; /* Need to look for matching name */ for (; idx < sk_X509_REVOKED_num(crl->crl.revoked); idx++) { rev = sk_X509_REVOKED_value(crl->crl.revoked, idx); if (ASN1_INTEGER_cmp(&rev->serialNumber, serial)) return 0; if (crl_revoked_issuer_match(crl, issuer, rev)) { if (ret) *ret = rev; if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) return 2; return 1; } } return 0; }
/* * openssl crl -in ca.crl -text */ void show_crl(char * ca_name) { X509_CRL * crl ; X509_REVOKED * rev ; int i, total ; STACK_OF(X509_REVOKED) * rev_list ; BIO * out ; if ((crl = load_crl(ca_name))==NULL) { printf("No CRL found\n"); return ; } rev_list = X509_CRL_get_REVOKED(crl); total = sk_X509_REVOKED_num(rev_list); out = BIO_new(BIO_s_file()); out = BIO_new_fp(stdout, BIO_NOCLOSE); BIO_printf(out, "-- Revoked certificates found in CRL\n"); for (i=0 ; i<total ; i++) { rev=sk_X509_REVOKED_value(rev_list, i); BIO_printf(out, "serial: "); i2a_ASN1_INTEGER(out, rev->serialNumber); BIO_printf(out, "\n date: "); ASN1_TIME_print(out, rev->revocationDate); BIO_printf(out, "\n\n"); } X509_CRL_free(crl); BIO_free_all(out); return ; }
static LUA_FUNCTION(openssl_crl_count) { X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); int n = sk_X509_REVOKED_num(crl->crl->revoked); lua_pushinteger(L, n); return 1; }
int X509_CRL_sort(X509_CRL *c) { int i; X509_REVOKED *r; /* sort the data so it will be written in serial * number order */ sk_X509_REVOKED_sort(c->crl->revoked); for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) { r=sk_X509_REVOKED_value(c->crl->revoked, i); r->sequence=i; } return 1; }
static LUA_FUNCTION(openssl_crl_get) { X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); int i = luaL_checkint(L, 2); if (i >= 0 && i < sk_X509_REVOKED_num(crl->crl->revoked)) { X509_REVOKED *revoked = sk_X509_REVOKED_value(crl->crl->revoked, i); lua_newtable(L); #if OPENSSL_VERSION_NUMBER > 0x10000000L AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(revoked->reason), string); #else { int crit = 0; void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string); ASN1_ENUMERATED_free(reason); } #endif PUSH_ASN1_INTEGER(L, revoked->serialNumber); lua_setfield(L, -2, "serialNumber"); PUSH_ASN1_TIME(L, revoked->revocationDate); lua_setfield(L, -2, "revocationDate"); if (crl->crl->extensions) { lua_pushstring(L, "extensions"); openssl_sk_x509_extension_totable(L, crl->crl->extensions); lua_rawset(L, -3); } return 1; } else lua_pushnil(L); return 1; }
static VALUE ossl_x509crl_get_revoked(VALUE self) { X509_CRL *crl; int i, num; X509_REVOKED *rev; VALUE ary, revoked; GetX509CRL(self, crl); num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); if (num < 0) { OSSL_Debug("num < 0???"); return rb_ary_new(); } ary = rb_ary_new2(num); for(i=0; i<num; i++) { /* NO DUP - don't free! */ rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); revoked = ossl_x509revoked_new(rev); rb_ary_push(ary, revoked); } return ary; }
/* based on the code of stunnel utility */ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { X509_STORE* store; X509_STORE_CTX store_ctx; X509_OBJECT obj; X509_NAME* subject; X509_NAME* issuer; X509* cert; X509_CRL* crl; X509_REVOKED* revoked; EVP_PKEY* pubkey; int i, n, rc; ASN1_TIME* next_update = NULL; if (!preverify_ok) { return 0; } if ((store = pthread_getspecific(tls_store_key)) == NULL) { ERROR("Failed to get thread-specific X509 store"); return 1; /* fail */ } cert = X509_STORE_CTX_get_current_cert(x509_ctx); subject = X509_get_subject_name(cert); issuer = X509_get_issuer_name(cert); /* try to retrieve a CRL corresponding to the _subject_ of * the current certificate in order to verify it's integrity */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, store, NULL, NULL); rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl = obj.data.crl; if (rc > 0 && crl) { next_update = X509_CRL_get_nextUpdate(crl); /* verify the signature on this CRL */ pubkey = X509_get_pubkey(cert); if (X509_CRL_verify(crl, pubkey) <= 0) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); X509_OBJECT_free_contents(&obj); if (pubkey) { EVP_PKEY_free(pubkey); } return 0; /* fail */ } if (pubkey) { EVP_PKEY_free(pubkey); } /* check date of CRL to make sure it's not expired */ if (!next_update) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } if (X509_cmp_current_time(next_update) < 0) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_HAS_EXPIRED); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } X509_OBJECT_free_contents(&obj); } /* try to retrieve a CRL corresponding to the _issuer_ of * the current certificate in order to check for revocation */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, store, NULL, NULL); rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl = obj.data.crl; if (rc > 0 && crl) { /* check if the current certificate is revoked by this CRL */ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for (i = 0; i < n; i++) { revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { ERROR("Certificate revoked"); X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_REVOKED); X509_OBJECT_free_contents(&obj); return 0; /* fail */ } } X509_OBJECT_free_contents(&obj); } return 1; /* success */ }
static LUA_FUNCTION(openssl_crl_parse) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); int n, i; lua_newtable(L); AUXILIAR_SET(L, -1, "version", X509_CRL_get_version(crl), integer); /* hash as used in CA directories to lookup cert by subject name */ { char buf[32]; snprintf(buf, sizeof(buf), "%08lx", X509_NAME_hash(X509_CRL_get_issuer(crl))); AUXILIAR_SET(L, -1, "hash", buf, string); } { const EVP_MD *digest = EVP_get_digestbyname("sha1"); unsigned char md[EVP_MAX_MD_SIZE]; int n = sizeof(md); if (X509_CRL_digest(crl, digest, md, (unsigned int*)&n)) { lua_newtable(L); AUXILIAR_SET(L, -1, "alg", OBJ_nid2sn(EVP_MD_type(digest)), string); AUXILIAR_SETLSTR(L, -1, "hash", (const char*)md, n); lua_setfield(L, -2, "fingerprint"); } } openssl_push_xname_asobject(L, X509_CRL_get_issuer(crl)); lua_setfield(L, -2, "issuer"); PUSH_ASN1_TIME(L,X509_CRL_get_lastUpdate(crl)); lua_setfield(L, -2, "lastUpdate"); PUSH_ASN1_TIME(L,X509_CRL_get_nextUpdate(crl)); lua_setfield(L, -2, "nextUpdate"); openssl_push_x509_algor(L, crl->crl->sig_alg); lua_setfield(L, -2, "sig_alg"); PUSH_ASN1_INTEGER(L, X509_CRL_get_ext_d2i(crl, NID_crl_number, NULL, NULL)); lua_setfield(L, -2, "crl_number"); PUSH_OBJECT(sk_X509_EXTENSION_dup(crl->crl->extensions),"openssl.stack_of_x509_extension"); lua_setfield(L, -2, "extensions"); n = sk_X509_REVOKED_num(crl->crl->revoked); lua_newtable(L); for (i = 0; i < n; i++) { X509_REVOKED *revoked = sk_X509_REVOKED_value(crl->crl->revoked, i); lua_newtable(L); #if OPENSSL_VERSION_NUMBER > 0x10000000L AUXILIAR_SET(L, -1, "CRLReason", reason_flags[revoked->reason].lname, string); #else { int crit = 0; void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); AUXILIAR_SET(L, -1, "CRLReason", reason_flags[ASN1_ENUMERATED_get(reason)].lname, string); ASN1_ENUMERATED_free(reason); } #endif PUSH_ASN1_INTEGER(L, revoked->serialNumber); lua_setfield(L,-2, "serialNumber"); PUSH_ASN1_TIME(L, revoked->revocationDate); lua_setfield(L,-2, "revocationDate"); PUSH_OBJECT(sk_X509_EXTENSION_dup(revoked->extensions),"openssl.stack_of_x509_extension"); lua_setfield(L,-2, "extensions"); lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "revoked"); return 1; }
static int crl_set_issuers(X509_CRL *crl) { int i, j; GENERAL_NAMES *gens, *gtmp; STACK_OF(X509_REVOKED) *revoked; revoked = X509_CRL_get_REVOKED(crl); gens = NULL; for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); STACK_OF(X509_EXTENSION) *exts; ASN1_ENUMERATED *reason; X509_EXTENSION *ext; gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL); if (!gtmp && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (gtmp) { gens = gtmp; if (!crl->issuers) { crl->issuers = sk_GENERAL_NAMES_new_null(); if (!crl->issuers) return 0; } if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) return 0; } rev->issuer = gens; reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); if (!reason && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (reason) { rev->reason = ASN1_ENUMERATED_get(reason); ASN1_ENUMERATED_free(reason); } else rev->reason = CRL_REASON_NONE; /* Check for critical CRL entry extensions */ exts = rev->extensions; for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { ext = sk_X509_EXTENSION_value(exts, j); if (X509_EXTENSION_get_critical(ext)) { if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer) continue; crl->flags |= EXFLAG_CRITICAL; break; } } } return 1; }
int ca_x509_verify_crl(struct conf **confs, X509 *peer_cert, const char *ssl_peer_cn) { int n; int i; int ret=-1; BIO *in=NULL; BIGNUM *bnser=NULL; X509_CRL *crl=NULL; X509_REVOKED *revoked; ASN1_INTEGER *serial=NULL; char *crl_path=NULL; const char *ca_name=get_string(confs[OPT_CA_NAME]); int crl_check=get_int(confs[OPT_CA_CRL_CHECK]); if(!crl_check || !ca_name || !*ca_name || !gca_dir) { ret=0; goto end; } if(!(crl_path=get_crl_path(ca_name))) goto end; if(!(in=BIO_new_file(crl_path, "r"))) { logp("CRL: cannot read: %s\n", crl_path); goto end; } if(!(crl=PEM_read_bio_X509_CRL(in, NULL, NULL, NULL))) { logp_ssl_err("CRL: cannot read CRL from file %s\n", crl_path); goto end; } if(X509_NAME_cmp(X509_CRL_get_issuer(crl), X509_get_issuer_name(peer_cert))) { logp_ssl_err("CRL: CRL %s is from a different issuer than the issuer of certificate %\ns", crl_path, ssl_peer_cn); goto end; } n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for(i=0; i<n; i++) { revoked=(X509_REVOKED *) sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); if(!ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(peer_cert))) { serial=X509_get_serialNumber(peer_cert); bnser=ASN1_INTEGER_to_BN(serial, NULL); logp_ssl_err("CRL check failed: %s (%s) is revoked\n", ssl_peer_cn, serial ? BN_bn2hex(bnser):"not available"); goto end; } } ret=0; end: if(in) BIO_free(in); if(crl) X509_CRL_free(crl); free_w(&crl_path); return ret; }
int X509_CRL_print(BIO *out, X509_CRL *x) { char buf[256]; unsigned char *s; STACK_OF(X509_REVOKED) *rev; X509_REVOKED *r; long l; int i, j, n; BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l); i = OBJ_obj2nid(x->sig_alg->algorithm); BIO_printf(out, "%8sSignature Algorithm: %s\n", "", (i == NID_undef) ? "NONE" : OBJ_nid2ln(i)); X509_NAME_oneline(X509_CRL_get_issuer(x),buf,256); BIO_printf(out,"%8sIssuer: %s\n","",buf); BIO_printf(out,"%8sLast Update: ",""); ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x)); BIO_printf(out,"\n%8sNext Update: ",""); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x)); else BIO_printf(out,"NONE"); BIO_printf(out,"\n"); n=X509_CRL_get_ext_count(x); if (n > 0) { BIO_printf(out,"%8sCRL extensions:\n",""); for (i=0; i<n; i++) ext_print(out, X509_CRL_get_ext(x, i)); } rev = X509_CRL_get_REVOKED(x); if(sk_X509_REVOKED_num(rev)) BIO_printf(out, "Revoked Certificates:\n"); else BIO_printf(out, "No Revoked Certificates.\n"); for(i = 0; i < sk_X509_REVOKED_num(rev); i++) { r = sk_X509_REVOKED_value(rev, i); BIO_printf(out," Serial Number: "); i2a_ASN1_INTEGER(out,r->serialNumber); BIO_printf(out,"\n Revocation Date: ",""); ASN1_TIME_print(out,r->revocationDate); BIO_printf(out,"\n"); for(j = 0; j < X509_REVOKED_get_ext_count(r); j++) ext_print(out, X509_REVOKED_get_ext(r, j)); } i=OBJ_obj2nid(x->sig_alg->algorithm); BIO_printf(out," Signature Algorithm: %s", (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); s = x->signature->data; n = x->signature->length; for (i=0; i<n; i++, s++) { if ((i%18) == 0) BIO_write(out,"\n ",9); BIO_printf(out,"%02x%s",*s, ((i+1) == n)?"":":"); } BIO_write(out,"\n",1); return 1; }
/* based on BSD-style licensed code of mod_ssl */ static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) { X509_STORE_CTX store_ctx; X509_OBJECT obj; X509_NAME *subject; X509_NAME *issuer; X509 *cert; X509_CRL *crl; X509_REVOKED *revoked; EVP_PKEY *pubkey; long serial; int i, n, rc; char *cp; ASN1_TIME *last_update=NULL, *next_update=NULL; /* determine certificate ingredients in advance */ cert=X509_STORE_CTX_get_current_cert(callback_ctx); subject=X509_get_subject_name(cert); issuer=X509_get_issuer_name(cert); /* try to retrieve a CRL corresponding to the _subject_ of * the current certificate in order to verify it's integrity */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL); rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl=obj.data.crl; if(rc>0 && crl) { cp=X509_NAME_oneline(subject, NULL, 0); s_log(LOG_INFO, "CRL: issuer: %s", cp); OPENSSL_free(cp); last_update=X509_CRL_get_lastUpdate(crl); next_update=X509_CRL_get_nextUpdate(crl); log_time(LOG_INFO, "CRL: last update", last_update); log_time(LOG_INFO, "CRL: next update", next_update); /* verify the signature on this CRL */ pubkey=X509_get_pubkey(cert); if(X509_CRL_verify(crl, pubkey)<=0) { s_log(LOG_WARNING, "CRL: Invalid signature"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); X509_OBJECT_free_contents(&obj); if(pubkey) EVP_PKEY_free(pubkey); return 0; /* reject connection */ } if(pubkey) EVP_PKEY_free(pubkey); /* check date of CRL to make sure it's not expired */ if(!next_update) { s_log(LOG_WARNING, "CRL: Invalid nextUpdate field"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } if(X509_cmp_current_time(next_update)<0) { s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates"); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } X509_OBJECT_free_contents(&obj); } /* try to retrieve a CRL corresponding to the _issuer_ of * the current certificate in order to check for revocation */ memset((char *)&obj, 0, sizeof obj); X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL); rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj); X509_STORE_CTX_cleanup(&store_ctx); crl=obj.data.crl; if(rc>0 && crl) { /* check if the current certificate is revoked by this CRL */ n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for(i=0; i<n; i++) { revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); if(ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { serial=ASN1_INTEGER_get(revoked->serialNumber); cp=X509_NAME_oneline(issuer, NULL, 0); s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) " "revoked per CRL from issuer %s", serial, serial, cp); OPENSSL_free(cp); X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED); X509_OBJECT_free_contents(&obj); return 0; /* reject connection */ } } X509_OBJECT_free_contents(&obj); } return 1; /* accept connection */ }
const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup(const PKI_X509_CRL *x, const PKI_INTEGER *s ) { long long end = 0; const STACK_OF(X509_REVOKED) * r_sk = NULL; X509_CRL *crl = NULL; // Input Checks if (!x || !s) return (NULL); // Gets the revoked stack if ((r_sk = X509_CRL_get_REVOKED(crl)) == NULL) { // No Entries in the CRL return NULL; } /* Set the end point to the last one */ if ((end = (long long) sk_X509_REVOKED_num(r_sk) - 1) < 0) return NULL; // Gets a casted pointer crl = (X509_CRL *) x; /* Look for serial number of certificate in CRL */ // rtmp.serialNumber = (ASN1_INTEGER *) serial; // ok = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); #if OPENSSL_VERSION_NUMBER >= 0x1010000fL PKI_X509_CRL_ENTRY *r = NULL; // Gets the reference in r X509_CRL_get0_by_serial(crl, &r, (PKI_INTEGER *)s); #else long long curr = 0; long long cmp_val = 0; const PKI_X509_CRL_ENTRY *r = NULL; for( curr = 0 ; curr <= end ; curr++ ) { const PKI_X509_CRL_ENTRY *r = NULL; const PKI_INTEGER * s_pnt; // Pointer to the SN in the X509_REVOKED struct // Gets the X509_REVOKED entry if ((r = sk_X509_REVOKED_value( r_sk, (int) curr )) != NULL) { // # if OPENSSL_VERSION_NUMBER >= 0x1010000fL // // Gets the Serial Number // if ((s_pnt = X509_REVOKED_get0_serialNumber(r)) != NULL) { // // Checks the value against the CRL // if ((cmp_val = ASN1_INTEGER_cmp(s_pnt, s)) == 0) { // // Found // break; // } // } // # else if ((s_pnt = r->serialNumber) != NULL) { // Checks the value against the CRL if ((cmp_val = ASN1_INTEGER_cmp(s_pnt, s)) == 0) { // Found break; } } // # endif } } #endif return r; }