static X509_REVOKED *create_revoked(const BIGNUM* bn, time_t t, int reason) { X509_REVOKED *revoked = X509_REVOKED_new(); ASN1_TIME *tm = ASN1_TIME_new(); ASN1_INTEGER *it = BN_to_ASN1_INTEGER(bn, NULL);; ASN1_TIME_set(tm, t); X509_REVOKED_set_revocationDate(revoked, tm); X509_REVOKED_set_serialNumber(revoked, it); { ASN1_ENUMERATED * e = ASN1_ENUMERATED_new(); X509_EXTENSION * ext = X509_EXTENSION_new(); ASN1_ENUMERATED_set(e, reason); X509_EXTENSION_set_data(ext, e); X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason)); X509_REVOKED_add_ext(revoked, ext, 0); X509_EXTENSION_free(ext); ASN1_ENUMERATED_free(e); } ASN1_TIME_free(tm); ASN1_INTEGER_free(it); return revoked; }
static X509_REVOKED *create_revoked(lua_State*L, const BIGNUM* bn, time_t t, int reason) { X509_REVOKED *revoked = X509_REVOKED_new(); ASN1_TIME *tm = ASN1_TIME_new(); ASN1_INTEGER *it = BN_to_ASN1_INTEGER((BIGNUM*)bn, NULL);; ASN1_TIME_set(tm, t); X509_REVOKED_set_revocationDate(revoked, tm); X509_REVOKED_set_serialNumber(revoked, it); #if OPENSSL_VERSION_NUMBER > 0x10000000L revoked->reason = reason; #else { ASN1_ENUMERATED * e = ASN1_ENUMERATED_new(); X509_EXTENSION * ext = X509_EXTENSION_new(); ASN1_ENUMERATED_set(e, reason); X509_EXTENSION_set_data(ext, e); X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason)); X509_REVOKED_add_ext(revoked, ext, 0); X509_EXTENSION_free(ext); ASN1_ENUMERATED_free(e); } #endif ASN1_TIME_free(tm); ASN1_INTEGER_free(it); return revoked; }
void openssl_x509_crl() { RSA *r; BIO *bp; int len; FILE *fp; BIGNUM *bne; X509_CRL *crl; EVP_PKEY *pkey; X509_NAME *issuer; ASN1_INTEGER *serial; X509_REVOKED *revoked; ASN1_TIME *lastUpdate, *nextUpdate, *rvTime; unsigned char *buf, *p, tmp[MAX1_LEN] = "crl cert"; printf("\nX509_CRL info:\n"); bne = BN_new(); BN_set_word(bne, RSA_3); r = RSA_new(); RSA_generate_key_ex(r, MAX1_LEN, bne, NULL); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, r); crl = X509_CRL_new(); X509_CRL_set_version(crl, 3); issuer = X509_NAME_new(); X509_NAME_add_entry_by_NID(issuer, NID_commonName, V_ASN1_PRINTABLESTRING, tmp, 10, -1, 0); X509_CRL_set_issuer_name(crl, issuer); lastUpdate = ASN1_TIME_new(); ASN1_TIME_set(lastUpdate, time(NULL)); X509_CRL_set_lastUpdate(crl, lastUpdate); nextUpdate = ASN1_TIME_new(); ASN1_TIME_set(nextUpdate, time(NULL) + 1280); X509_CRL_set_nextUpdate(crl, nextUpdate); revoked = X509_REVOKED_new(); serial = ASN1_INTEGER_new(); ASN1_INTEGER_set(serial, 1280); X509_REVOKED_set_serialNumber(revoked, serial); rvTime = ASN1_TIME_new(); ASN1_TIME_set(rvTime, time(NULL) + 2000); X509_CRL_set_nextUpdate(crl, rvTime); X509_REVOKED_set_revocationDate(revoked, rvTime); X509_CRL_add0_revoked(crl, revoked); X509_CRL_sort(crl); X509_CRL_sign(crl, pkey, EVP_md5()); bp = BIO_new(BIO_s_file()); BIO_set_fp(bp, stdout, BIO_NOCLOSE); X509_CRL_print(bp, crl); len = i2d_X509_CRL(crl, NULL); buf = (unsigned char *)malloc(len + 10); p = buf; len = i2d_X509_CRL(crl, &p); fp = fopen("/tmp/crl.crl", "wb"); fwrite(buf, 1, len, fp); fclose(fp); free(buf); BIO_free(bp); X509_CRL_free(crl); }
DWORD VMCACreateRevokedFromCert( X509 *pCert, X509_REVOKED **pRevoked) { DWORD dwError = 0; X509_REVOKED *pTempRev = NULL; ASN1_TIME *pRevTime = NULL; ASN1_ENUMERATED *pCode = NULL; pCode = ASN1_ENUMERATED_new(); if(pCode == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } pTempRev = X509_REVOKED_new(); if (pTempRev == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } pRevTime = ASN1_TIME_new(); if (pRevTime == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } ASN1_TIME_set(pRevTime, time(NULL)); dwError = X509_REVOKED_set_serialNumber(pTempRev, X509_get_serialNumber(pCert)); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_SERIAL_FAIL); dwError = X509_REVOKED_set_revocationDate(pTempRev, pRevTime); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_TIME_FAIL); //TODO : Fix the UNSPECIFIED to real valid reason // which users can pass in. ASN1_ENUMERATED_set(pCode, CRL_REASON_UNSPECIFIED); dwError = X509_REVOKED_add1_ext_i2d(pTempRev, NID_crl_reason, pCode, 0, 0); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_REASON_FAIL); *pRevoked = pTempRev; cleanup : if(pRevTime != NULL) { ASN1_TIME_free(pRevTime); } if(pCode !=NULL) { ASN1_ENUMERATED_free(pCode); } return dwError; error: if(pTempRev != NULL) { X509_REVOKED_free(pTempRev); } goto cleanup; }
DWORD VMCACreateRevokedFromCert_Reason( ASN1_INTEGER *asnSerial, DWORD dwRevokedDate, VMCA_CRL_REASON certRevokeReason, X509_REVOKED **pRevoked) { DWORD dwError = 0; X509_REVOKED *pTempRev = NULL; ASN1_TIME *pRevTime = NULL; ASN1_ENUMERATED *pCode = NULL; pCode = ASN1_ENUMERATED_new(); if(pCode == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } pTempRev = X509_REVOKED_new(); if (pTempRev == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } pRevTime = ASN1_TIME_new(); if (pRevTime == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } ASN1_TIME_set(pRevTime, (time_t)dwRevokedDate); dwError = X509_REVOKED_set_serialNumber(pTempRev, asnSerial); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_SERIAL_FAIL); dwError = X509_REVOKED_set_revocationDate(pTempRev, pRevTime); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_TIME_FAIL); ASN1_ENUMERATED_set(pCode, certRevokeReason); dwError = X509_REVOKED_add1_ext_i2d(pTempRev, NID_crl_reason, pCode, 0, 0); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_REASON_FAIL); *pRevoked = pTempRev; cleanup : if(pRevTime != NULL) { ASN1_TIME_free(pRevTime); } if(pCode !=NULL) { ASN1_ENUMERATED_free(pCode); } return dwError; error: if(pTempRev != NULL) { X509_REVOKED_free(pTempRev); } goto cleanup; }
X509_REVOKED *openssl_X509_REVOKED(lua_State*L, int snidx, int timeidx, int reasonidx) { X509_REVOKED *revoked = X509_REVOKED_new(); const char* serial = luaL_checkstring(L, snidx); BIGNUM * bn = NULL; ASN1_TIME *tm = NULL; int reason = 0; ASN1_INTEGER *it = NULL; if(!BN_hex2bn(&bn, serial)) { goto end; }; if(lua_isnumber(L,timeidx) || lua_isnoneornil(L, timeidx)) { time_t t; time(&t); t = luaL_optinteger(L, 3, (lua_Integer)t); tm = ASN1_TIME_new(); ASN1_TIME_set(tm,t); } else if(lua_isstring(L, timeidx)) { } else { goto end; } if(lua_isnumber(L, reasonidx) || lua_isnoneornil(L, reasonidx)) { reason = luaL_optinteger(L, reasonidx, 0); if(reason < 0 || reason >= reason_num) { goto end; } } else if(lua_isstring(L, reasonidx)) { const char* s = lua_tostring(L, reasonidx); reason = openssl_get_revoke_reason(s); if(reason < 0 || reason >= reason_num) { goto end; } } else { goto end; }; it = BN_to_ASN1_INTEGER(bn,NULL); X509_REVOKED_set_revocationDate(revoked, tm); X509_REVOKED_set_serialNumber(revoked, it); #if OPENSSL_VERSION_NUMBER > 0x10000000L revoked->reason = reason; #else /* { ASN1_ENUMERATED * e = ASN1_ENUMERATED_new(); X509_EXTENSION * ext = X509_EXTENSION_new(); ASN1_ENUMERATED_set(e, reason); X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason)); X509_EXTENSION_set_data(ext,e); if(!revoked->extensions) revoked->extensions = sk_X509_EXTENSION_new_null(); X509_REVOKED_add_ext() sk_X509_REVOKED_push(revoked->extensions,ext); X509_EXTENSION_free(ext); ASN1_ENUMERATED_free(e); } */ #endif ASN1_TIME_free(tm); ASN1_INTEGER_free(it); BN_free(bn); return revoked; end: X509_REVOKED_free(revoked); ASN1_TIME_free(tm); ASN1_INTEGER_free(it); BN_free(bn); return NULL; }
PKI_X509_CRL_ENTRY * PKI_X509_CRL_ENTRY_new_serial( const char *serial, PKI_X509_CRL_REASON reason, const PKI_TIME *revDate, const PKI_X509_PROFILE *profile ) { PKI_X509_CRL_ENTRY *entry = NULL; // Entry to be added to the CRL PKI_INTEGER * s_int = NULL; // ASN1 Integer PKI_TIME * a_date = NULL; // ASN1 Rev Date // Input check if (!serial) { PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing serial number"); return NULL; } // Allocates the Memory for the entry if((entry = (PKI_X509_CRL_ENTRY *) X509_REVOKED_new()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // If no revocation date is provided, let's use "now" if (!revDate && (a_date = PKI_TIME_new(0)) == NULL) { // Can not allocate the revocation date time PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } else { // Gets the Pointer from the caller a_date = (PKI_TIME *)revDate; } // Generates the integer carrying the serial number if ((s_int = PKI_INTEGER_new_char(serial)) != NULL) { // Sets the serial number in the X509_REVOKED structure if (X509_REVOKED_set_serialNumber(entry, s_int) == 1) { // Sets the revocation date if (a_date && !X509_REVOKED_set_revocationDate((X509_REVOKED *) entry, a_date)) { PKI_ERROR(PKI_ERR_GENERAL, "Can not assign revocation date"); goto err; } // All Ok here } else { // Error While assigning the serial PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not assign the serial (%s)", serial); goto err; } } else { // Error generating the ASN1 Integer PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not convert serial %s to Integer", serial); goto err; } if (reason != PKI_CRL_REASON_UNSPECIFIED) { int supported_reason = -1; ASN1_ENUMERATED *rtmp = ASN1_ENUMERATED_new(); switch (reason ) { case PKI_CRL_REASON_CERTIFICATE_HOLD: case PKI_CRL_REASON_HOLD_INSTRUCTION_REJECT: if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, PKI_OID_get("holdInstructionReject"), 0, 0)) { PKI_ERROR(PKI_ERR_X509_CRL, "Can not add holdInstructionReject"); goto err; } if (revDate && !X509_REVOKED_add1_ext_i2d(entry, NID_invalidity_date, (PKI_TIME *)revDate, 0, 0)) { PKI_ERROR(PKI_ERR_X509_CRL, "Can not add invalidity date"); goto err; } supported_reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; /* --- Deprecated in RFC 5280 --- case PKI_CRL_REASON_HOLD_INSTRUCTION_NONE: if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, PKI_OID_get( "holdInstructionReject"), 0, 0)) { goto err; }; if( revDate && !X509_REVOKED_add1_ext_i2d ( entry, NID_invalidity_date, revDate, 0, 0)) { goto err; }; reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; */ case PKI_CRL_REASON_HOLD_INSTRUCTION_CALLISSUER: if (!X509_REVOKED_add1_ext_i2d( entry, NID_hold_instruction_code, PKI_OID_get( "holdInstructionCallIssuer"), 0, 0)) { goto err; } if( revDate && !X509_REVOKED_add1_ext_i2d( entry, NID_invalidity_date, (PKI_TIME *)revDate, 0, 0)) { goto err; } supported_reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; case PKI_CRL_REASON_KEY_COMPROMISE: case PKI_CRL_REASON_CA_COMPROMISE: case PKI_CRL_REASON_AFFILIATION_CHANGED: case PKI_CRL_REASON_SUPERSEDED: case PKI_CRL_REASON_CESSATION_OF_OPERATION: case PKI_CRL_REASON_REMOVE_FROM_CRL: case PKI_CRL_REASON_PRIVILEGE_WITHDRAWN: case PKI_CRL_REASON_AA_COMPROMISE: PKI_ERROR(PKI_ERR_GENERAL, "CRL Reason Not Implemented Yet %d", reason); break; default: PKI_ERROR(PKI_ERR_GENERAL, "CRL Reason Unknown %d", reason); supported_reason = -1; break; } if (supported_reason >= 0) { if (!ASN1_ENUMERATED_set(rtmp, supported_reason)) goto err; if (!X509_REVOKED_add1_ext_i2d( entry, NID_crl_reason, rtmp, 0, 0)) goto err; } /* if( reason == CRL_REASON_HOLD_INSTRUCTION ) { // if (!X509_REVOKED_add1_ext_i2d ( entry, // NID_invalidity_date, revDate, 0, 0)) { // goto err; // }; // if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, // PKI_OID_get( "holdInstructionReject"), 0, 0)) { // goto err; // }; }; */ } /* if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) goto err; if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) { rtmp = ASN1_ENUMERATED_new(); if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) goto err; if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) goto err; } if (rev && comp_time) { if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0)) goto err; } if (rev && hold) { if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0)) goto err; } */ // Free Allocated Memory if (s_int) PKI_INTEGER_free(s_int); if (a_date && !revDate) PKI_TIME_free(a_date); // Returns the created entry return entry; err: // Free Allocated memory if (s_int) PKI_INTEGER_free(s_int); if (a_date && !revDate) PKI_TIME_free(a_date); if (entry) X509_REVOKED_free((X509_REVOKED *) entry); // Returns null (error) return NULL; }
int addToCRL(char* pemSigningKey, char* pemOldCrl, char* pemRevokedCert, char* result) { int err = 0; BIO* bioSigningKey = BIO_new_mem_buf(pemSigningKey, -1); if (!bioSigningKey) { return ERR_peek_error(); } BIO* bioRevCert = BIO_new_mem_buf(pemRevokedCert, -1); if (!bioRevCert) { BIO_free(bioSigningKey); return ERR_peek_error(); } BIO* bioOldCRL = BIO_new_mem_buf(pemOldCrl, -1); if (!bioOldCRL) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return ERR_peek_error(); } X509* badCert = PEM_read_bio_X509(bioRevCert, NULL, NULL, NULL); if (!badCert) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return ERR_peek_error(); } EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioSigningKey, NULL, NULL, NULL); if (!caKey) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return -18; } X509_CRL* crl = PEM_read_bio_X509_CRL(bioOldCRL, NULL, NULL, NULL); if (!crl) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return ERR_peek_error(); } X509_REVOKED* revoked = X509_REVOKED_new(); X509_REVOKED_set_serialNumber(revoked, X509_get_serialNumber(badCert)); ASN1_TIME* tmptm = ASN1_TIME_new(); X509_gmtime_adj(tmptm, long(0)); X509_REVOKED_set_revocationDate(revoked, tmptm); //set the reason? Not yet. // ASN1_ENUMERATED* rtmp = ASN1_ENUMERATED_new(); // ASN1_ENUMERATED_set(rtmp, reasonCode); // goto err; // if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) // goto err; // } if(!(err = X509_CRL_add0_revoked(crl,revoked))) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return err; } X509_CRL_sort(crl); if(!(err=X509_CRL_sign(crl,caKey,EVP_sha1()))) { BIO_free(bioSigningKey); BIO_free(bioRevCert); return err; } BIO *mem = BIO_new(BIO_s_mem()); PEM_write_bio_X509_CRL(mem,crl); BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_read(mem, result, bptr->length); BIO_free(bioRevCert); BIO_free(bioSigningKey); BIO_free(bioOldCRL); BIO_free(mem); return 0; }
/* * Revoke one certificate at a time * No check performed to see if certificate already revoked. */ void revoke_cert(char * ca_name, char * name) { char filename[FIELD_SZ+5]; FILE * f ; X509_CRL * crl ; X509 * cert ; ASN1_INTEGER * r_serial ; ASN1_INTEGER * crlnum ; X509_REVOKED * rev ; ASN1_TIME * tm ; identity ca ; BIO * out ; BIGNUM * b_crlnum ; /* Find requested certificate by name */ sprintf(filename, "%s.crt", name); if ((f=fopen(filename, "r"))==NULL) { fprintf(stderr, "Cannot find: %s\n", filename); return ; } cert = PEM_read_X509(f, NULL, NULL, NULL); fclose(f); /* Get certificate serial number */ r_serial = X509_get_serialNumber(cert); /* Find out if if was already revoked */ /* Make a revoked object with that serial */ rev = X509_REVOKED_new(); X509_REVOKED_set_serialNumber(rev, r_serial); X509_free(cert); /* Set reason to unspecified */ rev->reason = ASN1_ENUMERATED_get(CRL_REASON_UNSPECIFIED); /* Load or create new CRL */ if ((crl = load_crl(ca_name))==NULL) { crl = X509_CRL_new(); X509_CRL_set_version(crl, 1); /* Set CRL number */ crlnum = ASN1_INTEGER_new(); ASN1_INTEGER_set(crlnum, 1); X509_CRL_add1_ext_i2d(crl, NID_crl_number, crlnum, 0, 0); ASN1_INTEGER_free(crlnum); } else { crlnum = X509_CRL_get_ext_d2i(crl, NID_crl_number, 0, 0); b_crlnum = ASN1_INTEGER_to_BN(crlnum, NULL); BN_add_word(b_crlnum, 1); BN_to_ASN1_INTEGER(b_crlnum, crlnum); BN_free(b_crlnum); X509_CRL_add1_ext_i2d(crl, NID_crl_number, crlnum, 0, X509V3_ADD_REPLACE_EXISTING); ASN1_INTEGER_free(crlnum); } /* What time is it? */ tm = ASN1_TIME_new(); X509_gmtime_adj(tm, 0); X509_REVOKED_set_revocationDate(rev, tm); X509_CRL_set_lastUpdate(crl, tm); /* Set CRL next update to a year from now */ X509_gmtime_adj(tm, 365*24*60*60); X509_CRL_set_nextUpdate(crl, tm); ASN1_TIME_free(tm); /* Add revoked to CRL */ X509_CRL_add0_revoked(crl, rev); X509_CRL_sort(crl); /* Load root key to sign CRL */ if (load_ca(ca_name, &ca)!=0) { fprintf(stderr, "Cannot find CA key/crt\n"); return ; } X509_CRL_set_issuer_name(crl, X509_get_subject_name(ca.cert)); X509_free(ca.cert); /* Sign CRL */ X509_CRL_sign(crl, ca.key, EVP_sha256()); EVP_PKEY_free(ca.key); /* Dump CRL */ sprintf(filename, "%s.crl", ca_name); if ((f = fopen(filename, "wb"))==NULL) { fprintf(stderr, "Cannot write %s: aborting\n", filename); X509_CRL_free(crl); return ; } out = BIO_new(BIO_s_file()); BIO_set_fp(out, f, BIO_NOCLOSE); PEM_write_bio_X509_CRL(out, crl); BIO_free_all(out); fclose(f); X509_CRL_free(crl); return ; }