static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, X509_REVOKED *rev) { int i; if (!rev->issuer) { if (!nm) return 1; if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) return 1; return 0; } if (!nm) nm = X509_CRL_get_issuer(crl); for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); if (gen->type != GEN_DIRNAME) continue; if (!X509_NAME_cmp(nm, gen->d.directoryName)) return 1; } return 0; }
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) { int idp_only = 0; /* Set various flags according to IDP */ crl->idp_flags |= IDP_PRESENT; if (idp->onlyuser > 0) { idp_only++; crl->idp_flags |= IDP_ONLYUSER; } if (idp->onlyCA > 0) { idp_only++; crl->idp_flags |= IDP_ONLYCA; } if (idp->onlyattr > 0) { idp_only++; crl->idp_flags |= IDP_ONLYATTR; } if (idp_only > 1) crl->idp_flags |= IDP_INVALID; if (idp->indirectCRL > 0) crl->idp_flags |= IDP_INDIRECT; if (idp->onlysomereasons) { crl->idp_flags |= IDP_REASONS; if (idp->onlysomereasons->length > 0) crl->idp_reasons = idp->onlysomereasons->data[0]; if (idp->onlysomereasons->length > 1) crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); crl->idp_reasons &= CRLDP_ALL_REASONS; } DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); }
static PyObject * z_py_zorp_crl_getattr(PyObject *o, char *name) { ZorpCRL *self = (ZorpCRL *) o; PyObject *res = NULL; BIO *bio; guint len; gchar *mem; gchar buf[512]; if (strcmp(name, "blob") == 0) { bio = BIO_new(BIO_s_mem()); PEM_write_bio_X509_CRL(bio, self->crl); len = BIO_get_mem_data(bio, &mem); res = PyString_FromStringAndSize(mem, len); BIO_free(bio); } else if (strcmp(name, "issuer") == 0) { X509_NAME_oneline(X509_CRL_get_issuer(self->crl), buf, sizeof(buf)); res = PyString_FromString(buf); } else { PyErr_SetString(PyExc_AttributeError, "Attribute not found"); } return res; }
static LUA_FUNCTION(openssl_crl_issuer) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); if (lua_isnone(L, 2)) { return openssl_push_xname_asobject(L, X509_CRL_get_issuer(crl)); } else if (auxiliar_isclass(L, "openssl.x509_name", 2)) { X509_NAME* xn = CHECK_OBJECT(2, X509_NAME, "openssl.x509_name"); int ret = X509_CRL_set_issuer_name(crl, xn); return openssl_pushresult(L, ret); } else if (auxiliar_isclass(L, "openssl.x509", 2)) { X509* x = CHECK_OBJECT(2, X509, "openssl.x509"); int ret = X509_CRL_set_issuer_name(crl, X509_get_issuer_name(x)); return openssl_pushresult(L, ret); } else { luaL_argerror(L, 2, "only accept x509 or x509_name object"); } return 0; }
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 VALUE ossl_x509crl_get_issuer(VALUE self) { X509_CRL *crl; GetX509CRL(self, crl); return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */ }
UString UCrl::getIssuer(X509_CRL* _crl, bool ldap) { U_TRACE(0, "UCrl::getIssuer(%p,%b)", _crl, ldap) U_INTERNAL_ASSERT_POINTER(_crl) X509_NAME* n = X509_CRL_get_issuer(_crl); return UCertificate::getName(n, ldap); }
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; }
/***************************************************************************** * * Low-level x509 functions * *****************************************************************************/ static int xmlSecOpenSSLX509VerifyCRL(X509_STORE* xst, X509_CRL *crl ) { X509_STORE_CTX *xsc = NULL; X509_OBJECT *xobj = NULL; EVP_PKEY *pkey = NULL; int ret; xmlSecAssert2(xst != NULL, -1); xmlSecAssert2(crl != NULL, -1); xsc = X509_STORE_CTX_new(); if(xsc == NULL) { xmlSecOpenSSLError(NULL, "X509_STORE_CTX_new"); goto err; } xobj = X509_OBJECT_new(); if(xobj == NULL) { xmlSecOpenSSLError(NULL, "X509_OBJECT_new"); goto err; } ret = X509_STORE_CTX_init(xsc, xst, NULL, NULL); if(ret != 1) { xmlSecOpenSSLError(NULL, "X509_STORE_CTX_init"); goto err; } ret = X509_STORE_CTX_get_by_subject(xsc, X509_LU_X509, X509_CRL_get_issuer(crl), xobj); if(ret <= 0) { xmlSecOpenSSLError(NULL, "X509_STORE_CTX_get_by_subject"); goto err; } pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj)); if(pkey == NULL) { xmlSecOpenSSLError(NULL, "X509_get_pubkey"); goto err; } ret = X509_CRL_verify(crl, pkey); EVP_PKEY_free(pkey); if(ret != 1) { xmlSecOpenSSLError(NULL, "X509_CRL_verify"); } X509_STORE_CTX_free(xsc); X509_OBJECT_free(xobj); return((ret == 1) ? 1 : 0); err: X509_STORE_CTX_free(xsc); X509_OBJECT_free(xobj); 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; }
static int handle_certificate(const char *filename, const char *fullpath) { STACK_OF(X509_INFO) *inf; X509_INFO *x; BIO *b; const char *ext; unsigned char digest[EVP_MAX_MD_SIZE]; X509_NAME *name = NULL; int i, type, ret = -1; ext = strrchr(filename, '.'); if (ext == NULL) return 0; for (i = 0; i < countof(file_extensions); i++) { if (strcasecmp(file_extensions[i], ext+1) == 0) break; } if (i >= countof(file_extensions)) return -1; b = BIO_new_file(fullpath, "r"); if (!b) return -1; inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL); BIO_free(b); if (!inf) return -1; if (sk_X509_INFO_num(inf) == 1) { x = sk_X509_INFO_value(inf, 0); if (x->x509) { type = TYPE_CERT; name = X509_get_subject_name(x->x509); X509_digest(x->x509, evpmd, digest, NULL); } else if (x->crl) { type = TYPE_CRL; name = X509_CRL_get_issuer(x->crl); X509_CRL_digest(x->crl, evpmd, digest, NULL); } if (name && do_hash_new) add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0); if (name && do_hash_old) add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0); } else { fprintf(stderr, "WARNING: %s does not contain exactly one certificate or CRL: skipping\n", filename); } sk_X509_INFO_pop_free(inf, X509_INFO_free); return ret; }
void Crl::Load() { if(!download.Get(url.c_str(), path.c_str())) { pf_log[W_INFO] << "CRL download failed"; throw DownloadFailed(); } pf_log[W_INFO] << "Loading CRL file : \"" << path << "\"."; if(crl) { X509_CRL_free(crl); crl = NULL; } // TODO: simplify-me with openssl's BIO FILE* f = fopen(path.c_str(), "r"); if(!f) throw BadCRL(std::string(strerror(errno))); if(fseek(f, 0, SEEK_END)) throw BadCRL(std::string(strerror(errno))); size_t file_size = ftell(f); rewind(f); char buf[file_size]; if(fread(buf, file_size, 1, f) <= 0) { fclose(f); throw BadCRL(std::string(strerror(errno))); } if(file_size > INT_MAX) throw BadCRL(std::string("File is too big")); BIO* raw_crl = BIO_new_mem_buf(buf, (int)file_size); crl = PEM_read_bio_X509_CRL(raw_crl, NULL, NULL, NULL); BIO_free(raw_crl); if(!crl) { std::string str = std::string(ERR_error_string( ERR_get_error(), NULL)); throw BadCRL(str); } char* str = X509_NAME_oneline (X509_CRL_get_issuer (crl), 0, 0); pf_log[W_INFO] << "CRL issued by: " << str; }
/* * We will put into store X509 object from passed data in buffer only * when object name match passed. To compare both names we use our * method "ssh_X509_NAME_cmp"(it is more general). */ static int/*bool*/ ldaplookup_data2store( int type, X509_NAME* name, void* buf, int len, X509_STORE* store ) { int ok = 0; BIO *mbio; if (name == NULL) return(0); if (buf == NULL) return(0); if (len <= 0) return(0); if (store == NULL) return(0); mbio = BIO_new_mem_buf(buf, len); if (mbio == NULL) return(0); switch (type) { case X509_LU_X509: { X509 *x509 = d2i_X509_bio(mbio, NULL); if(x509 == NULL) goto exit; /*This is correct since lookup method is by subject*/ if (ssh_X509_NAME_cmp(name, X509_get_subject_name(x509)) != 0) goto exit; ok = X509_STORE_add_cert(store, x509); } break; case X509_LU_CRL: { X509_CRL *crl = d2i_X509_CRL_bio(mbio, NULL); if(crl == NULL) goto exit; if (ssh_X509_NAME_cmp(name, X509_CRL_get_issuer(crl)) != 0) goto exit; ok = X509_STORE_add_crl(store, crl); } break; } exit: if (mbio != NULL) BIO_free_all(mbio); #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_data2store: ok=%d\n", ok); #endif return(ok); }
static int hash_file(int dirfd, const char *filename) { STACK_OF(X509_INFO) *inf; X509_INFO *x; BIO *b; int i, count = 0; unsigned char digest[EVP_MAX_MD_SIZE]; b = BIO_openat(dirfd, filename); if (!b) return -1; inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL); BIO_free(b); if (!inf) return -1; for(i = 0; i < sk_X509_INFO_num(inf); i++) { x = sk_X509_INFO_value(inf, i); if (x->x509) { X509_digest(x->x509, evpmd, digest, NULL); link_file(dirfd, filename, TYPE_CERT, X509_subject_name_hash(x->x509), digest); count++; } if (x->crl) { X509_CRL_digest(x->crl, evpmd, digest, NULL); link_file(dirfd, filename, TYPE_CRL, X509_NAME_hash(X509_CRL_get_issuer(x->crl)), digest); count++; } } sk_X509_INFO_pop_free(inf, X509_INFO_free); if (count == 0) { fprintf(stderr, "WARNING: %s does not contain a certificate or CRL: skipping\n", filename); } return count; }
/***************************************************************************** * * Low-level x509 functions * *****************************************************************************/ static int xmlSecOpenSSLX509VerifyCRL(X509_STORE* xst, X509_CRL *crl ) { X509_STORE_CTX xsc; X509_OBJECT xobj; EVP_PKEY *pkey; int ret; xmlSecAssert2(xst != NULL, -1); xmlSecAssert2(crl != NULL, -1); X509_STORE_CTX_init(&xsc, xst, NULL, NULL); ret = X509_STORE_get_by_subject(&xsc, X509_LU_X509, X509_CRL_get_issuer(crl), &xobj); if(ret <= 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "X509_STORE_get_by_subject", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } pkey = X509_get_pubkey(xobj.data.x509); X509_OBJECT_free_contents(&xobj); if(pkey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "X509_get_pubkey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = X509_CRL_verify(crl, pkey); EVP_PKEY_free(pkey); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "X509_CRL_verify", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); } X509_STORE_CTX_cleanup (&xsc); return((ret == 1) ? 1 : 0); }
X509_NAME* HsOpenSSL_X509_CRL_get_issuer(X509_CRL* crl) { return X509_CRL_get_issuer(crl); }
DWORD VMCAUpdateCrlCAAttribute( PVMCA_LDAP_CONTEXT pContext, PSTR pszConfigurationDN, PSTR pszCrl ) { DWORD dwError = 0; PSTR pszCADN = NULL; PSTR pszCrlAuthorityKeyId = NULL; PSTR pszCAContainerDN = NULL; X509_CRL* pCrl = NULL; ATTR_SEARCH_RESULT attrSearchResult = ATTR_NOT_FOUND; X509_NAME* pIssuer = NULL; PSTR pszCAIssuerDN = NULL; PSTR pszFoundCADN = NULL; dwError = VMCAPEMToX509Crl(pszCrl, &pCrl); BAIL_ON_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszCAContainerDN, "CN=%s,%s", CA_CONTAINER_NAME, pszConfigurationDN); BAIL_ON_ERROR(dwError); dwError = VMCAGetCrlAuthKeyIdHexString(pCrl, &pszCrlAuthorityKeyId); if (dwError == ERROR_SUCCESS) { if (!IsNullOrEmptyString(pszCrlAuthorityKeyId)) { dwError = VMCAAllocateStringPrintfA( &pszCADN, "CN=%s,%s", pszCrlAuthorityKeyId, pszCAContainerDN); BAIL_ON_ERROR(dwError); } } if (!pszCADN) { pIssuer = X509_CRL_get_issuer(pCrl); // Don't free dwError = VMCAGetX509Name(pIssuer, XN_FLAG_COMPAT, &pszCAIssuerDN); BAIL_ON_ERROR(dwError); if (pszCAIssuerDN == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } } dwError = VMCACheckCAObject( pContext, pszCAContainerDN, pszCADN, pszCAIssuerDN, &pszFoundCADN ); if (dwError == ERROR_INVALID_STATE && pszCAIssuerDN) { VMCA_LOG_ERROR("More than one CA found with given issuer DN: %s", pszCAIssuerDN); } BAIL_ON_ERROR(dwError); if (!pszFoundCADN) { dwError = ERROR_NOT_FOUND; BAIL_ON_ERROR(dwError); } dwError = VMCACheckAttribute( pContext, pszFoundCADN, ATTR_CRL, pszCrl, &attrSearchResult ); BAIL_ON_ERROR(dwError); if (attrSearchResult != ATTR_MATCH) { dwError = VMCAUpdateAttribute(pContext, pszFoundCADN, ATTR_CRL, pszCrl, (attrSearchResult == ATTR_NOT_FOUND)); BAIL_ON_ERROR(dwError); } cleanup: VMCA_SAFE_FREE_MEMORY(pszFoundCADN); VMCA_SAFE_FREE_MEMORY(pszCAIssuerDN); VMCA_SAFE_FREE_STRINGA(pszCADN); VMCA_SAFE_FREE_STRINGA(pszCrlAuthorityKeyId); VMCA_SAFE_FREE_STRINGA(pszCAContainerDN); if (pCrl) { X509_CRL_free(pCrl); } return dwError; error: goto cleanup; }
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; }
/** *失効リストチェック関数 * @author University of Tsukuba * @param *pInData 証明書データ * @param lInLen 証明書データ長 * @param *data CRLファイルデータ * @param len CRLファイルデータレングス * @return long 0:未失効 1:失効中 -1:異常 * @since 2008.02 * @version 1.0 */ long IDMan_CmCheckCRL(void *pInData, long lInLen, void * data,unsigned long int len ) { long lRet=-1L; /*FILE *fp;*/ X509 *x509=0x00; X509_CRL *x509crl=0x00; X509_NAME *x509crlissuer = 0x00; int iRet=0; int idx; X509_REVOKED rtmp; char *p,*p2; char szErrBuff[1024]; BIO * BIOptr; ERR_load_crypto_strings(); IDMan_StMemset(szErrBuff, 0x00, sizeof(szErrBuff)); /** 証明書データパラメータチェックを行う。 */ /** エラー発生した場合、 */ if (pInData == 0x00) { /** −処理を中断する。 */ return lRet; } /** 証明書長データパラメータチェックを行う。 */ /** エラー発生した場合、 */ if (lInLen == 0) { /** −処理を中断する。 */ return lRet; } /** 失効データパラメータチェックを行う。 */ /** 失効データが存在しない場合、 */ if (data==0x00 || len == 0) { /** −正常終了する。 */ lRet =0; return lRet; } /** X509構造体の初期化を行う。 */ /** エラー発生した場合、 */ if((x509 = X509_new())== 0x00) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); return lRet; } /** DERファイルから、X509構造体にデータを読み込む。 */ /** BIO構造の作成を行う。 */ BIOptr = BIO_new(BIO_s_mem()); /** BIO構造のリセットを行う。 */ iRet = BIO_reset(BIOptr); /** エラー発生した場合、 */ if(iRet != 1) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); BIO_free(BIOptr); return lRet; } /** BIO構造へ公開鍵証明書データの設定を行う。 */ iRet = BIO_write(BIOptr,pInData,lInLen); /** エラー発生した場合、 */ if( iRet != lInLen ) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); BIO_free(BIOptr); return lRet; } /** X509構造体の作成を行う。 */ x509 =(X509 *) d2i_X509_bio(BIOptr,0x00); /** エラー発生した場合、 */ if((x509 == 0x00)) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); if(x509 !=0x00) X509_free(x509); BIO_free(BIOptr); return lRet; } /** BIO構造の解放を行う。 */ BIO_free(BIOptr); /** issuerDNの取得を行う。 */ X509_NAME *x509issuer = X509_get_issuer_name(x509); p = X509_NAME_oneline(x509issuer, 0, 0); /** CRL情報の取得を行う。 */ x509crl = X509_CRL_new(); /** BIO構造の作成を行う。 */ BIOptr = BIO_new(BIO_s_mem()); /** BIO構造のリセットを行う。 */ iRet = BIO_reset(BIOptr); /** エラー発生した場合、 */ if(iRet != 1) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); BIO_free(BIOptr); return lRet; } /** BIO構造へ失効リストデータの設定を行う。 */ iRet = BIO_write(BIOptr,data,len); /** エラー発生した場合、 */ if( iRet != (int)len ) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); BIO_free(BIOptr); return lRet; } /** x509crl構造へ失効リストデータの設定を行う。 */ x509crl = (X509_CRL *) d2i_X509_CRL_bio(BIOptr,0x00); /** エラー発生した場合、 */ if(x509crl==0x00) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); if(x509 !=0x00) X509_free(x509); if(x509crl !=0x00) X509_CRL_free(x509crl); BIO_free(BIOptr); return lRet; } /** BIO構造の解放を行う。 */ BIO_free(BIOptr); /** シリアル番号の取得を行う。 */ rtmp.serialNumber = X509_get_serialNumber(x509); /** CRLのissuerDNの取得を行う。 */ /** エラー発生した場合、 */ x509crlissuer = X509_CRL_get_issuer(x509crl); if ( x509crlissuer == 0x00 ) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); if(x509 !=0x00) X509_free(x509); if(x509crl !=0x00) X509_CRL_free(x509crl); return lRet; } /** 証明書とCRLのissuerDNの比較を行う。 */ p2 = X509_NAME_oneline(x509crlissuer, 0, 0); /** エラー発生した場合、 */ if( strcmp(p, p2) != 0) { /** −処理を中断する。 */ ERR_error_string(ERR_get_error(), szErrBuff); if(x509 !=0x00) X509_free(x509); if(x509crl !=0x00) X509_CRL_free(x509crl); return lRet; } /** CRLのシリアル番号をソートする。 */ if (!sk_is_sorted(x509crl->crl->revoked)) { sk_sort(x509crl->crl->revoked); } /** CRLのシリアル番号を検索する。 */ idx = sk_X509_REVOKED_find(x509crl->crl->revoked, &rtmp); /** 該当シリアル番号が存在する場合、 */ if (idx >= 0) { /** −戻り値に1を設定する。 */ lRet =1; } /** 該当シリアル番号が存在しない場合、 */ else { /** −戻り値に0を設定する。 */ lRet =0; } /** X509の開放を行う。 */ if(x509 !=0x00) X509_free(x509); /** X509CRLの開放を行う。 */ if(x509crl !=0x00) X509_CRL_free(x509crl); return lRet; }
int crl_main(int argc, char **argv) { unsigned long nmflag = 0; X509_CRL *x = NULL; int ret = 1, i; BIO *out = NULL; X509_STORE *store = NULL; X509_STORE_CTX ctx; X509_LOOKUP *lookup = NULL; X509_OBJECT xobj; EVP_PKEY *pkey; const EVP_MD *digest; char *digest_name = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath", NULL) == -1) { perror("pledge"); exit(1); } } if (bio_out == NULL) { if ((bio_out = BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); } } digest = EVP_sha256(); memset(&crl_config, 0, sizeof(crl_config)); crl_config.informat = FORMAT_PEM; crl_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) { crl_usage(); goto end; } if (crl_config.cafile != NULL || crl_config.capath != NULL) crl_config.verify = 1; if (crl_config.nameopt != NULL) { if (set_name_ex(&nmflag, crl_config.nameopt) != 1) { fprintf(stderr, "Invalid -nameopt argument '%s'\n", crl_config.nameopt); goto end; } } if (digest_name != NULL) { if ((digest = EVP_get_digestbyname(digest_name)) == NULL) { fprintf(stderr, "Unknown message digest algorithm '%s'\n", digest_name); goto end; } } x = load_crl(crl_config.infile, crl_config.informat); if (x == NULL) goto end; if (crl_config.verify) { store = X509_STORE_new(); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; if (!X509_LOOKUP_load_file(lookup, crl_config.cafile, X509_FILETYPE_PEM)) X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; if (!X509_LOOKUP_add_dir(lookup, crl_config.capath, X509_FILETYPE_PEM)) X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); ERR_clear_error(); if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, X509_CRL_get_issuer(x), &xobj); if (i <= 0) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } pkey = X509_get_pubkey(xobj.data.x509); X509_OBJECT_free_contents(&xobj); if (!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); EVP_PKEY_free(pkey); if (i < 0) goto end; if (i == 0) BIO_printf(bio_err, "verify failure\n"); else BIO_printf(bio_err, "verify OK\n"); } /* Print requested information the order that the flags were given. */ for (i = 1; i <= argc; i++) { if (crl_config.issuer == i) { print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); } if (crl_config.crlnumber == i) { ASN1_INTEGER *crlnum; crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); BIO_printf(bio_out, "crlNumber="); if (crlnum) { i2a_ASN1_INTEGER(bio_out, crlnum); ASN1_INTEGER_free(crlnum); } else BIO_puts(bio_out, "<NONE>"); BIO_printf(bio_out, "\n"); } if (crl_config.hash == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash(X509_CRL_get_issuer(x))); } #ifndef OPENSSL_NO_MD5 if (crl_config.hash_old == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash_old(X509_CRL_get_issuer(x))); } #endif if (crl_config.lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x)); BIO_printf(bio_out, "\n"); } if (crl_config.nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x)); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); } if (crl_config.fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_CRL_digest(x, digest, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(bio_out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j = 0; j < (int) n; j++) { BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (crl_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, crl_config.outfile) <= 0) { perror(crl_config.outfile); goto end; } } if (crl_config.text) X509_CRL_print(out, x); if (crl_config.noout) { ret = 0; goto end; } if (crl_config.outformat == FORMAT_ASN1) i = (int) i2d_X509_CRL_bio(out, x); else if (crl_config.outformat == FORMAT_PEM) i = PEM_write_bio_X509_CRL(out, x); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write CRL\n"); goto end; } ret = 0; end: BIO_free_all(out); BIO_free_all(bio_out); bio_out = NULL; X509_CRL_free(x); if (store) { X509_STORE_CTX_cleanup(&ctx); X509_STORE_free(store); } return (ret); }
const void * PKI_X509_CRL_get_data(const PKI_X509_CRL * x, PKI_X509_DATA type ) { const void *ret = NULL; PKI_X509_CRL_VALUE *tmp_x = NULL; if (!x || !x->value) return NULL; tmp_x = x->value; switch( type ) { case PKI_X509_DATA_VERSION: #if OPENSSL_VERSION_NUMBER > 0x1010000fL ret = (tmp_x)->crl.version; #else ret = (tmp_x)->crl->version; #endif // ret = X509_CRL_get_version((X509_CRL *) x); break; case PKI_X509_DATA_ISSUER: ret = X509_CRL_get_issuer ((X509_CRL *) tmp_x); break; case PKI_X509_DATA_NOTAFTER: case PKI_X509_DATA_NEXTUPDATE: #if OPENSSL_VERSION_NUMBER > 0x1010000fL ret = X509_CRL_get0_nextUpdate ((X509_CRL *) tmp_x); #else ret = X509_CRL_get_nextUpdate ((X509_CRL *) tmp_x); #endif break; case PKI_X509_DATA_NOTBEFORE: case PKI_X509_DATA_LASTUPDATE: #if OPENSSL_VERSION_NUMBER > 0x1010000fL ret = X509_CRL_get0_lastUpdate ((X509_CRL *) tmp_x); #else ret = X509_CRL_get_lastUpdate ((X509_CRL *) tmp_x); #endif break; case PKI_X509_DATA_EXTENSIONS: // ret = X509_CRL_get_extensions((X509_CRL *) x ); PKI_log_debug("To Be implemented!"); ret = NULL; // ret = X509_CRL_get_algor((X509_CRL *) x ); break; case PKI_X509_DATA_SIGNATURE: #if OPENSSL_VERSION_NUMBER > 0x1010000fL X509_CRL_get0_signature((X509_CRL *)tmp_x, (const ASN1_BIT_STRING **)&ret, NULL); #else ret = tmp_x->signature; #endif // ret = tmp_x->signature; // ret = X509_CRL_get_signature ((X509_CRL *) x); break; case PKI_X509_DATA_SIGNATURE_ALG1: #if OPENSSL_VERSION_NUMBER > 0x1010000fL // X509_CRL_get0_signature((X509_CRL *)tmp_x, // NULL, (const X509_ALGOR **)&ret); ret = &(((PKI_X509_CRL_FULL *)tmp_x)->crl.sig_alg); #else if (tmp_x->crl) ret = tmp_x->crl->sig_alg; #endif break; case PKI_X509_DATA_ALGORITHM: case PKI_X509_DATA_SIGNATURE_ALG2: #if OPENSSL_VERSION_NUMBER > 0x1010000fL X509_CRL_get0_signature((X509_CRL *)tmp_x, NULL, (const X509_ALGOR **)&ret); #else ret = tmp_x->sig_alg; #endif break; default: /* Not Recognized/Supported DATATYPE */ return (NULL); } return (ret); }
int MAIN(int argc, char **argv) { unsigned long nmflag = 0; X509_CRL *x = NULL; char *CAfile = NULL, *CApath = NULL; int ret = 1, i, num, badops = 0, badsig = 0; BIO *out = NULL; int informat, outformat, keyformat; char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0, text = 0; #ifndef OPENSSL_NO_MD5 int hash_old = 0; #endif int fingerprint = 0, crlnumber = 0; const char **pp; X509_STORE *store = NULL; X509_STORE_CTX ctx; X509_LOOKUP *lookup = NULL; X509_OBJECT xobj; EVP_PKEY *pkey; int do_ver = 0; const EVP_MD *md_alg, *digest = EVP_sha1(); apps_startup(); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; if (bio_out == NULL) if ((bio_out = BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_out = BIO_push(tmpbio, bio_out); } #endif } informat = FORMAT_PEM; outformat = FORMAT_PEM; keyformat = FORMAT_PEM; argc--; argv++; num = 0; while (argc >= 1) { #ifdef undef if (sgx_strcmp(*argv, "-p") == 0) { if (--argc < 1) goto bad; if (!args_from_file(++argv, Nargc, Nargv)) { goto end; } */} #endif if (sgx_strcmp(*argv, "-inform") == 0) { if (--argc < 1) goto bad; informat = str2fmt(*(++argv)); } else if (sgx_strcmp(*argv, "-outform") == 0) { if (--argc < 1) goto bad; outformat = str2fmt(*(++argv)); } else if (sgx_strcmp(*argv, "-in") == 0) { if (--argc < 1) goto bad; infile = *(++argv); } else if (sgx_strcmp(*argv, "-gendelta") == 0) { if (--argc < 1) goto bad; crldiff = *(++argv); } else if (sgx_strcmp(*argv, "-key") == 0) { if (--argc < 1) goto bad; keyfile = *(++argv); } else if (sgx_strcmp(*argv, "-keyform") == 0) { if (--argc < 1) goto bad; keyformat = str2fmt(*(++argv)); } else if (sgx_strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (sgx_strcmp(*argv, "-CApath") == 0) { if (--argc < 1) goto bad; CApath = *(++argv); do_ver = 1; } else if (sgx_strcmp(*argv, "-CAfile") == 0) { if (--argc < 1) goto bad; CAfile = *(++argv); do_ver = 1; } else if (sgx_strcmp(*argv, "-verify") == 0) do_ver = 1; else if (sgx_strcmp(*argv, "-text") == 0) text = 1; else if (sgx_strcmp(*argv, "-hash") == 0) hash = ++num; #ifndef OPENSSL_NO_MD5 else if (sgx_strcmp(*argv, "-hash_old") == 0) hash_old = ++num; #endif else if (sgx_strcmp(*argv, "-nameopt") == 0) { if (--argc < 1) goto bad; if (!set_name_ex(&nmflag, *(++argv))) goto bad; } else if (sgx_strcmp(*argv, "-issuer") == 0) issuer = ++num; else if (sgx_strcmp(*argv, "-lastupdate") == 0) lastupdate = ++num; else if (sgx_strcmp(*argv, "-nextupdate") == 0) nextupdate = ++num; else if (sgx_strcmp(*argv, "-noout") == 0) noout = ++num; else if (sgx_strcmp(*argv, "-fingerprint") == 0) fingerprint = ++num; else if (sgx_strcmp(*argv, "-crlnumber") == 0) crlnumber = ++num; else if (sgx_strcmp(*argv, "-badsig") == 0) badsig = 1; else if ((md_alg = EVP_get_digestbyname(*argv + 1))) { /* ok */ digest = md_alg; } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } argc--; argv++; } if (badops) { bad: for (pp = crl_usage; (*pp != NULL); pp++) BIO_printf(bio_err, "%s", *pp); goto end; } ERR_load_crypto_strings(); x = load_crl(infile, informat); if (x == NULL) { goto end; } if (do_ver) { store = X509_STORE_new(); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); ERR_clear_error(); if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, X509_CRL_get_issuer(x), &xobj); if (i <= 0) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } pkey = X509_get_pubkey(xobj.data.x509); X509_OBJECT_free_contents(&xobj); if (!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); EVP_PKEY_free(pkey); if (i < 0) goto end; if (i == 0) BIO_printf(bio_err, "verify failure\n"); else BIO_printf(bio_err, "verify OK\n"); } if (crldiff) { X509_CRL *newcrl, *delta; if (!keyfile) { BIO_puts(bio_err, "Missing CRL signing key\n"); goto end; } newcrl = load_crl(crldiff, informat); if (!newcrl) goto end; pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); if (!pkey) { X509_CRL_free(newcrl); goto end; } delta = X509_CRL_diff(x, newcrl, pkey, digest, 0); X509_CRL_free(newcrl); EVP_PKEY_free(pkey); if (delta) { X509_CRL_free(x); x = delta; } else { BIO_puts(bio_err, "Error creating delta CRL\n"); goto end; } } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); } if (crlnumber == i) { ASN1_INTEGER *crlnum; crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); BIO_printf(bio_out, "crlNumber="); if (crlnum) { i2a_ASN1_INTEGER(bio_out, crlnum); ASN1_INTEGER_free(crlnum); } else BIO_puts(bio_out, "<NONE>"); BIO_printf(bio_out, "\n"); } if (hash == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash(X509_CRL_get_issuer(x))); } #ifndef OPENSSL_NO_MD5 if (hash_old == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash_old(X509_CRL_get_issuer(x))); } #endif if (lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x)); BIO_printf(bio_out, "\n"); } if (nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x)); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); } if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_CRL_digest(x, digest, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(bio_out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j = 0; j < (int)n; j++) { BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } } } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } if (text) X509_CRL_print(out, x); if (noout) { ret = 0; goto end; } if (badsig) x->signature->data[x->signature->length - 1] ^= 0x1; if (outformat == FORMAT_ASN1) i = (int)i2d_X509_CRL_bio(out, x); else if (outformat == FORMAT_PEM) i = PEM_write_bio_X509_CRL(out, x); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write CRL\n"); goto end; } ret = 0; end: if (ret != 0) ERR_print_errors(bio_err); BIO_free_all(out); BIO_free_all(bio_out); bio_out = NULL; X509_CRL_free(x); if (store) { X509_STORE_CTX_cleanup(&ctx); X509_STORE_free(store); } apps_shutdown(); OPENSSL_EXIT(ret); }
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 MAIN(int argc, char **argv) { X509_CRL *x=NULL; char *CAfile = NULL, *CApath = NULL; int ret=1,i,num,badops=0; BIO *out=NULL; int informat,outformat; char *infile=NULL,*outfile=NULL; int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0; int fingerprint = 0; char **pp,buf[256]; X509_STORE *store = NULL; X509_STORE_CTX ctx; X509_LOOKUP *lookup = NULL; X509_OBJECT xobj; EVP_PKEY *pkey; int do_ver = 0; const EVP_MD *md_alg,*digest=EVP_md5(); apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (bio_out == NULL) if ((bio_out=BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); #ifdef VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_out = BIO_push(tmpbio, bio_out); } #endif } informat=FORMAT_PEM; outformat=FORMAT_PEM; argc--; argv++; num=0; while (argc >= 1) { #ifdef undef if (strcmp(*argv,"-p") == 0) { if (--argc < 1) goto bad; if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/ } #endif if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-CApath") == 0) { if (--argc < 1) goto bad; CApath = *(++argv); do_ver = 1; } else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; CAfile = *(++argv); do_ver = 1; } else if (strcmp(*argv,"-verify") == 0) do_ver = 1; else if (strcmp(*argv,"-text") == 0) text = 1; else if (strcmp(*argv,"-hash") == 0) hash= ++num; else if (strcmp(*argv,"-issuer") == 0) issuer= ++num; else if (strcmp(*argv,"-lastupdate") == 0) lastupdate= ++num; else if (strcmp(*argv,"-nextupdate") == 0) nextupdate= ++num; else if (strcmp(*argv,"-noout") == 0) noout= ++num; else if (strcmp(*argv,"-fingerprint") == 0) fingerprint= ++num; else if ((md_alg=EVP_get_digestbyname(*argv + 1))) { /* ok */ digest=md_alg; } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: for (pp=crl_usage; (*pp != NULL); pp++) BIO_printf(bio_err,*pp); goto end; } ERR_load_crypto_strings(); x=load_crl(infile,informat); if (x == NULL) { goto end; } if(do_ver) { store = X509_STORE_new(); lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); if (lookup == NULL) goto end; if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); ERR_clear_error(); X509_STORE_CTX_init(&ctx, store, NULL, NULL); i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, X509_CRL_get_issuer(x), &xobj); if(i <= 0) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } pkey = X509_get_pubkey(xobj.data.x509); X509_OBJECT_free_contents(&xobj); if(!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); EVP_PKEY_free(pkey); if(i < 0) goto end; if(i == 0) BIO_printf(bio_err, "verify failure\n"); else BIO_printf(bio_err, "verify OK\n"); } if (num) { for (i=1; i<=num; i++) { if (issuer == i) { X509_NAME_oneline(X509_CRL_get_issuer(x), buf,256); BIO_printf(bio_out,"issuer= %s\n",buf); } if (hash == i) { BIO_printf(bio_out,"%08lx\n", X509_NAME_hash(X509_CRL_get_issuer(x))); } if (lastupdate == i) { BIO_printf(bio_out,"lastUpdate="); ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x)); BIO_printf(bio_out,"\n"); } if (nextupdate == i) { BIO_printf(bio_out,"nextUpdate="); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x)); else BIO_printf(bio_out,"NONE"); BIO_printf(bio_out,"\n"); } if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_CRL_digest(x,digest,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(bio_out,"%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j=0; j<(int)n; j++) { BIO_printf(bio_out,"%02X%c",md[j], (j+1 == (int)n) ?'\n':':'); } } } } out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (text) X509_CRL_print(out, x); if (noout) goto end; if (outformat == FORMAT_ASN1) i=(int)i2d_X509_CRL_bio(out,x); else if (outformat == FORMAT_PEM) i=PEM_write_bio_X509_CRL(out,x); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; } ret=0; end: BIO_free_all(out); BIO_free_all(bio_out); bio_out=NULL; X509_CRL_free(x); if(store) { X509_STORE_CTX_cleanup(&ctx); X509_STORE_free(store); } EXIT(ret); }
int crl_main(int argc, char **argv) { X509_CRL *x = NULL; BIO *out = NULL; X509_STORE *store = NULL; X509_STORE_CTX *ctx = NULL; X509_LOOKUP *lookup = NULL; X509_OBJECT *xobj = NULL; EVP_PKEY *pkey; const EVP_MD *digest = EVP_sha1(); unsigned long nmflag = 0; char nmflag_set = 0; char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; const char *CAfile = NULL, *CApath = NULL, *prog; OPTION_CHOICE o; int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0; int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0; int i; #ifndef OPENSSL_NO_MD5 int hash_old = 0; #endif prog = opt_init(argc, argv, crl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(crl_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_KEY: keyfile = opt_arg(); break; case OPT_GENDELTA: crldiff = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); do_ver = 1; break; case OPT_CAFILE: CAfile = opt_arg(); do_ver = 1; break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_HASH_OLD: #ifndef OPENSSL_NO_MD5 hash_old = ++num; #endif break; case OPT_VERIFY: do_ver = 1; break; case OPT_TEXT: text = 1; break; case OPT_HASH: hash = ++num; break; case OPT_ISSUER: issuer = ++num; break; case OPT_LASTUPDATE: lastupdate = ++num; break; case OPT_NEXTUPDATE: nextupdate = ++num; break; case OPT_NOOUT: noout = ++num; break; case OPT_FINGERPRINT: fingerprint = ++num; break; case OPT_CRLNUMBER: crlnumber = ++num; break; case OPT_BADSIG: badsig = 1; break; case OPT_NAMEOPT: nmflag_set = 1; if (!set_name_ex(&nmflag, opt_arg())) goto opthelp; break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; } } argc = opt_num_rest(); if (argc != 0) goto opthelp; if (!nmflag_set) nmflag = XN_FLAG_ONELINE; x = load_crl(infile, informat); if (x == NULL) goto end; if (do_ver) { if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; ctx = X509_STORE_CTX_new(); if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } xobj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, X509_CRL_get_issuer(x)); if (xobj == NULL) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj)); X509_OBJECT_free(xobj); if (!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); EVP_PKEY_free(pkey); if (i < 0) goto end; if (i == 0) BIO_printf(bio_err, "verify failure\n"); else BIO_printf(bio_err, "verify OK\n"); } if (crldiff) { X509_CRL *newcrl, *delta; if (!keyfile) { BIO_puts(bio_err, "Missing CRL signing key\n"); goto end; } newcrl = load_crl(crldiff, informat); if (!newcrl) goto end; pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); if (!pkey) { X509_CRL_free(newcrl); goto end; } delta = X509_CRL_diff(x, newcrl, pkey, digest, 0); X509_CRL_free(newcrl); EVP_PKEY_free(pkey); if (delta) { X509_CRL_free(x); x = delta; } else { BIO_puts(bio_err, "Error creating delta CRL\n"); goto end; } } if (badsig) { const ASN1_BIT_STRING *sig; X509_CRL_get0_signature(x, &sig, NULL); corrupt_signature(sig); } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); } if (crlnumber == i) { ASN1_INTEGER *crlnum; crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); BIO_printf(bio_out, "crlNumber="); if (crlnum) { i2a_ASN1_INTEGER(bio_out, crlnum); ASN1_INTEGER_free(crlnum); } else BIO_puts(bio_out, "<NONE>"); BIO_printf(bio_out, "\n"); } if (hash == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash(X509_CRL_get_issuer(x))); } #ifndef OPENSSL_NO_MD5 if (hash_old == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash_old(X509_CRL_get_issuer(x))); } #endif if (lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x)); BIO_printf(bio_out, "\n"); } if (nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get0_nextUpdate(x)) ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x)); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); } if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_CRL_digest(x, digest, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(bio_out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j = 0; j < (int)n; j++) { BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } } } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (text) X509_CRL_print(out, x); if (noout) { ret = 0; goto end; } if (outformat == FORMAT_ASN1) i = (int)i2d_X509_CRL_bio(out, x); else i = PEM_write_bio_X509_CRL(out, x); if (!i) { BIO_printf(bio_err, "unable to write CRL\n"); goto end; } ret = 0; end: if (ret != 0) ERR_print_errors(bio_err); BIO_free_all(out); X509_CRL_free(x); X509_STORE_CTX_free(ctx); X509_STORE_free(store); 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; }