From: Dr. Stephen Henson Date: Fri, 16 Feb 2001 01:35:44 +0000 (+0000) Subject: New options to 'ca' utility to support CRL entry extensions. X-Git-Tag: OpenSSL_0_9_6a-beta1~32^2~16 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=a6b7ffddac43c0805d02e7236034308f39bcd183 New options to 'ca' utility to support CRL entry extensions. Add revelant new X509V3 extensions. Add OIDs. Fix ASN1 memory leak code to pop info if external allocation used. --- diff --git a/CHANGES b/CHANGES index ca0ecc3a1a..4e23d17369 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,11 @@ Changes between 0.9.6 and 0.9.7 [xx XXX 2000] + *) New options to 'ca' utility to support V2 CRL entry extensions. + Currently CRL reason, invalidity date and hold instruction are + supported. Add new CRL extensions to V3 code and some new objects. + [Steve Henson] + *) Add "-rand" option also to s_client and s_server. [Lutz Jaenicke] diff --git a/apps/ca.c b/apps/ca.c index b84e842bc0..e0349a7656 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,14 @@ #define DB_TYPE_EXP 'E' #define DB_TYPE_VAL 'V' +/* Additional revocation information types */ + +#define REV_NONE 0 /* No addditional information */ +#define REV_CRL_REASON 1 /* Value is CRL reason code */ +#define REV_HOLD 2 /* Value is hold instruction */ +#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */ +#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */ + static char *ca_usage[]={ "usage: ca args\n", "\n", @@ -211,10 +220,12 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *startdate, char *enddate, int days, int batch, int verbose, X509_REQ *req, char *ext_sect, LHASH *conf); -static int do_revoke(X509 *x509, TXT_DB *db); +static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval); static int get_certificate_status(const char *ser_status, TXT_DB *db); static int do_updatedb(TXT_DB *db); static int check_time_format(char *str); +char *make_revocation_str(int rev_type, char *rev_arg); +int make_revoked(X509_REVOKED *rev, char *str); static LHASH *conf=NULL; static LHASH *extconf=NULL; static char *section=NULL; @@ -264,6 +275,8 @@ int MAIN(int argc, char **argv) char *extensions=NULL; char *extfile=NULL; char *crl_ext=NULL; + int rev_type = REV_NONE; + char *rev_arg = NULL; BIGNUM *serial=NULL; char *startdate=NULL; char *enddate=NULL; @@ -460,6 +473,30 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; crl_ext= *(++argv); } + else if (strcmp(*argv,"-crl_reason") == 0) + { + if (--argc < 1) goto bad; + rev_arg = *(++argv); + rev_type = REV_CRL_REASON; + } + else if (strcmp(*argv,"-crl_hold") == 0) + { + if (--argc < 1) goto bad; + rev_arg = *(++argv); + rev_type = REV_HOLD; + } + else if (strcmp(*argv,"-crl_compromise") == 0) + { + if (--argc < 1) goto bad; + rev_arg = *(++argv); + rev_type = REV_KEY_COMPROMISE; + } + else if (strcmp(*argv,"-crl_CA_compromise") == 0) + { + if (--argc < 1) goto bad; + rev_arg = *(++argv); + rev_type = REV_CA_COMPROMISE; + } else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; @@ -780,10 +817,9 @@ bad: goto err; } if ((pp[DB_type][0] == DB_TYPE_REV) && - !check_time_format(pp[DB_rev_date])) + !make_revoked(NULL, pp[DB_rev_date])) { - BIO_printf(bio_err,"entry %d: invalid revocation date\n", - i+1); + BIO_printf(bio_err," in entry %d\n", i+1); goto err; } if (!check_time_format(pp[DB_exp_date])) @@ -1325,6 +1361,7 @@ bad: /*****************************************************************/ if (gencrl) { + int crl_v2 = 0; if (!crl_ext) { crl_ext=CONF_get_string(conf,section,ENV_CRLEXT); @@ -1379,11 +1416,9 @@ bad: if (pp[DB_type][0] == DB_TYPE_REV) { if ((r=X509_REVOKED_new()) == NULL) goto err; - if (!ASN1_UTCTIME_set_string(r->revocationDate, - pp[DB_rev_date])) - goto err; - /* strcpy(r->revocationDate,pp[DB_rev_date]);*/ - + j = make_revoked(r, pp[DB_rev_date]); + if (!j) goto err; + if (j == 2) crl_v2 = 1; (void)BIO_reset(hex); if (!BIO_puts(hex,pp[DB_serial])) goto err; @@ -1429,13 +1464,18 @@ bad: X509V3_CTX crlctx; if (ci->version == NULL) if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err; - ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */ X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); X509V3_set_conf_lhash(&crlctx, conf); if (!X509V3_EXT_CRL_add_conf(conf, &crlctx, crl_ext, crl)) goto err; } + if (crl_ext || crl_v2) + { + if (ci->version == NULL) + if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err; + ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */ + } if (!X509_CRL_sign(crl,pkey,dgst)) goto err; @@ -1464,7 +1504,7 @@ bad: BIO_printf(bio_err,"unable to load '%s' certificate\n",infile); goto err; } - j=do_revoke(revcert,db); + j=do_revoke(revcert,db, rev_type, rev_arg); if (j <= 0) goto err; X509_free(revcert); @@ -2409,10 +2449,11 @@ static int check_time_format(char *str) return(ASN1_UTCTIME_check(&tm)); } -static int do_revoke(X509 *x509, TXT_DB *db) +static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value) { - ASN1_UTCTIME *tm=NULL, *revtm=NULL; + ASN1_UTCTIME *tm=NULL; char *row[DB_NUMBER],**rrow,**irow; + char *rev_str = NULL; BIGNUM *bn = NULL; int ok=-1,i; @@ -2481,7 +2522,7 @@ static int do_revoke(X509 *x509, TXT_DB *db) } /* Revoke Certificate */ - ok = do_revoke(x509,db); + ok = do_revoke(x509,db, type, value); goto err; @@ -2501,14 +2542,15 @@ static int do_revoke(X509 *x509, TXT_DB *db) else { BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]); - revtm = ASN1_UTCTIME_new(); - revtm=X509_gmtime_adj(revtm,0); + rev_str = make_revocation_str(type, value); + if (!rev_str) + { + BIO_printf(bio_err, "Error in revocation arguments\n"); + goto err; + } rrow[DB_type][0]='R'; rrow[DB_type][1]='\0'; - rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1); - memcpy(rrow[DB_rev_date],revtm->data,revtm->length); - rrow[DB_rev_date][revtm->length]='\0'; - ASN1_UTCTIME_free(revtm); + rrow[DB_rev_date] = rev_str; } ok=1; err: @@ -2679,3 +2721,245 @@ err: return (cnt); } + +static char *crl_reasons[] = { + /* CRL reason strings */ + "unspecified", + "keyCompromise", + "CACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "removeFromCRL", + /* Additional pseudo reasons */ + "holdInstruction", + "keyTime", + "CAkeyTime" +}; + +#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *)) + +/* Given revocation information convert to a DB string. + * The format of the string is: + * revtime[,reason,extra]. Where 'revtime' is the + * revocation time (the current time). 'reason' is the + * optional CRL reason and 'extra' is any additional + * argument + */ + +char *make_revocation_str(int rev_type, char *rev_arg) + { + char *reason = NULL, *other = NULL, *str; + ASN1_OBJECT *otmp; + ASN1_UTCTIME *revtm = NULL; + int i; + switch (rev_type) + { + case REV_NONE: + break; + + case REV_CRL_REASON: + for (i = 0; i < 8; i++) + { + if (!strcasecmp(rev_arg, crl_reasons[i])) + { + reason = crl_reasons[i]; + break; + } + } + if (reason == NULL) + { + BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg); + return NULL; + } + break; + + case REV_HOLD: + /* Argument is an OID */ + + otmp = OBJ_txt2obj(rev_arg, 0); + ASN1_OBJECT_free(otmp); + + if (otmp == NULL) + { + BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg); + return NULL; + } + + reason = "holdInstruction"; + other = rev_arg; + break; + + case REV_KEY_COMPROMISE: + case REV_CA_COMPROMISE: + + /* Argument is the key compromise time */ + if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) + { + BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg); + return NULL; + } + other = rev_arg; + if (rev_type == REV_KEY_COMPROMISE) + reason = "keyTime"; + else + reason = "CAkeyTime"; + + break; + + } + + revtm = X509_gmtime_adj(NULL, 0); + + i = revtm->length + 1; + + if (reason) i += strlen(reason) + 1; + if (other) i += strlen(other) + 1; + + str = OPENSSL_malloc(i); + + if (!str) return NULL; + + strcpy(str, (char *)revtm->data); + if (reason) + { + strcat(str, ","); + strcat(str, reason); + } + if (other) + { + strcat(str, ","); + strcat(str, other); + } + ASN1_UTCTIME_free(revtm); + return str; + } + +/* Convert revocation field to X509_REVOKED entry + * return code: + * 0 error + * 1 OK + * 2 OK and some extensions added (i.e. V2 CRL) + */ + +int make_revoked(X509_REVOKED *rev, char *str) + { + char *tmp = NULL; + char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; + int reason_code = -1; + int i, ret = 0; + ASN1_OBJECT *hold = NULL; + ASN1_GENERALIZEDTIME *comp_time = NULL; + ASN1_ENUMERATED *rtmp = NULL; + tmp = BUF_strdup(str); + + p = strchr(tmp, ','); + + rtime_str = tmp; + + if (p) + { + *p = '\0'; + p++; + reason_str = p; + p = strchr(p, ','); + if (p) + { + *p = '\0'; + arg_str = p + 1; + } + } + + if (rev && !ASN1_UTCTIME_set_string(rev->revocationDate, rtime_str)) + { + BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str); + goto err; + } + if (reason_str) + { + for (i = 0; i < NUM_REASONS; i++) + { + if(!strcasecmp(reason_str, crl_reasons[i])) + { + reason_code = i; + break; + } + } + if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) + { + BIO_printf(bio_err, "invalid reason code %s\n", reason_str); + goto err; + } + + if (reason_code == 7) + reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL; + else if (reason_code == 8) /* Hold instruction */ + { + if (!arg_str) + { + BIO_printf(bio_err, "missing hold instruction\n"); + goto err; + } + reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; + hold = OBJ_txt2obj(arg_str, 0); + + if (!hold) + { + BIO_printf(bio_err, "invalid object identifier %s\n", arg_str); + goto err; + } + } + else if ((reason_code == 9) || (reason_code == 10)) + { + if (!arg_str) + { + BIO_printf(bio_err, "missing compromised time\n"); + goto err; + } + comp_time = ASN1_GENERALIZEDTIME_new(); + if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) + { + BIO_printf(bio_err, "invalid compromised time %s\n", arg_str); + goto err; + } + if (reason_code == 9) + reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; + else + reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE; + } + } + + 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; + } + + if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) + ret = 2; + else ret = 1; + + err: + + if (tmp) OPENSSL_free(tmp); + ASN1_OBJECT_free(hold); + ASN1_GENERALIZEDTIME_free(comp_time); + ASN1_ENUMERATED_free(rtmp); + + return ret; + } diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 6ee0871394..51d2e16f84 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -672,6 +672,8 @@ ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp, ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp, long length); +DECLARE_ASN1_ITEM(ASN1_OBJECT) + DECLARE_STACK_OF(ASN1_OBJECT) DECLARE_ASN1_SET_OF(ASN1_OBJECT) diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h index 5e6efe2ccc..c854c96577 100644 --- a/crypto/asn1/asn1t.h +++ b/crypto/asn1/asn1t.h @@ -720,7 +720,6 @@ typedef struct ASN1_AUX_st { OPENSSL_EXTERN const ASN1_ITEM ASN1_BOOLEAN_it; OPENSSL_EXTERN const ASN1_ITEM ASN1_TBOOLEAN_it; OPENSSL_EXTERN const ASN1_ITEM ASN1_FBOOLEAN_it; -OPENSSL_EXTERN const ASN1_ITEM ASN1_OBJECT_it; OPENSSL_EXTERN const ASN1_ITEM ASN1_ANY_it; OPENSSL_EXTERN const ASN1_ITEM ASN1_SEQUENCE_it; OPENSSL_EXTERN const ASN1_ITEM CBIGNUM_it; diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index 3371dd13a7..798f9bfd5e 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -154,7 +154,12 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int if(asn1_cb) { i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); if(!i) goto auxerr; - if(i==2) return 1; + if(i==2) { +#ifdef CRYPTO_MDEBUG + if(it->sname) CRYPTO_pop_info(); +#endif + return 1; + } } if(!combine) { *pval = OPENSSL_malloc(it->size); diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 163ab034b6..e50f0459c7 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -61,12 +61,12 @@ * perl obj_dat.pl objects.h obj_dat.h */ -#define NUM_NID 406 -#define NUM_SN 404 -#define NUM_LN 404 -#define NUM_OBJ 378 +#define NUM_NID 410 +#define NUM_SN 408 +#define NUM_LN 408 +#define NUM_OBJ 382 -static unsigned char lvalues[3004]={ +static unsigned char lvalues[3028]={ 0x00, /* [ 0] OBJ_undef */ 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */ @@ -445,6 +445,10 @@ static unsigned char lvalues[3004]={ 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [2976] OBJ_aes_256_cbc */ 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [2985] OBJ_aes_256_ofb */ 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [2994] OBJ_aes_256_cfb */ +0x55,0x1D,0x17, /* [3003] OBJ_hold_instruction_code */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3006] OBJ_hold_instruction_none */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3013] OBJ_hold_instruction_call_issuer */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3020] OBJ_hold_instruction_reject */ }; static ASN1_OBJECT nid_objs[NUM_NID]={ @@ -1070,6 +1074,14 @@ static ASN1_OBJECT nid_objs[NUM_NID]={ {"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[2976]),0}, {"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb,9,&(lvalues[2985]),0}, {"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb,9,&(lvalues[2994]),0}, +{"holdInstructionCode","Hold Instruction Code", + NID_hold_instruction_code,3,&(lvalues[3003]),0}, +{"holdInstructionNone","Hold Instruction None", + NID_hold_instruction_none,7,&(lvalues[3006]),0}, +{"holdInstructionCallIssuer","Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer,7,&(lvalues[3013]),0}, +{"holdInstructionReject","Hold Instruction Reject", + NID_hold_instruction_reject,7,&(lvalues[3020]),0}, }; static ASN1_OBJECT *sn_objs[NUM_SN]={ @@ -1237,6 +1249,10 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={ &(nid_objs[372]),/* "extendedStatus" */ &(nid_objs[156]),/* "friendlyName" */ &(nid_objs[163]),/* "hmacWithSHA1" */ +&(nid_objs[408]),/* "holdInstructionCallIssuer" */ +&(nid_objs[406]),/* "holdInstructionCode" */ +&(nid_objs[407]),/* "holdInstructionNone" */ +&(nid_objs[409]),/* "holdInstructionReject" */ &(nid_objs[266]),/* "id-aca" */ &(nid_objs[355]),/* "id-aca-accessIdentity" */ &(nid_objs[354]),/* "id-aca-authenticationInfo" */ @@ -1494,6 +1510,10 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={ &(nid_objs[384]),/* "Experimental" */ &(nid_objs[372]),/* "Extended OCSP Status" */ &(nid_objs[172]),/* "Extension Request" */ +&(nid_objs[408]),/* "Hold Instruction Call Issuer" */ +&(nid_objs[406]),/* "Hold Instruction Code" */ +&(nid_objs[407]),/* "Hold Instruction None" */ +&(nid_objs[409]),/* "Hold Instruction Reject" */ &(nid_objs[294]),/* "IPSec End System" */ &(nid_objs[295]),/* "IPSec Tunnel" */ &(nid_objs[296]),/* "IPSec User" */ @@ -1922,6 +1942,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={ &(nid_objs[87]),/* OBJ_basic_constraints 2 5 29 19 */ &(nid_objs[88]),/* OBJ_crl_number 2 5 29 20 */ &(nid_objs[141]),/* OBJ_crl_reason 2 5 29 21 */ +&(nid_objs[406]),/* OBJ_hold_instruction_code 2 5 29 23 */ &(nid_objs[142]),/* OBJ_invalidity_date 2 5 29 24 */ &(nid_objs[140]),/* OBJ_delta_crl 2 5 29 27 */ &(nid_objs[103]),/* OBJ_crl_distribution_points 2 5 29 31 */ @@ -1964,6 +1985,9 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={ &(nid_objs[127]),/* OBJ_id_pkix 1 3 6 1 5 5 7 */ &(nid_objs[119]),/* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ &(nid_objs[ 2]),/* OBJ_pkcs 1 2 840 113549 1 */ +&(nid_objs[407]),/* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ +&(nid_objs[408]),/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ +&(nid_objs[409]),/* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ &(nid_objs[116]),/* OBJ_dsa 1 2 840 10040 4 1 */ &(nid_objs[113]),/* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ &(nid_objs[258]),/* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ diff --git a/crypto/objects/obj_mac.h b/crypto/objects/obj_mac.h index 616c98003e..c334ba674a 100644 --- a/crypto/objects/obj_mac.h +++ b/crypto/objects/obj_mac.h @@ -1863,3 +1863,25 @@ #define NID_aes_256_cfb 405 #define OBJ_aes_256_cfb OBJ_aes,44L +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 406 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 407 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 408 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 409 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 543b748c6c..70a573073d 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -403,3 +403,7 @@ aes_256_ecb 402 aes_256_cbc 403 aes_256_ofb 404 aes_256_cfb 405 +hold_instruction_code 406 +hold_instruction_none 407 +hold_instruction_call_issuer 408 +hold_instruction_reject 409 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index d3af5f276f..1497684fdc 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -612,3 +612,13 @@ aes 42 : AES-256-CBC : aes-256-cbc aes 43 : AES-256-OFB : aes-256-ofb aes 44 : AES-256-CFB : aes-256-cfb +# Hold instruction CRL entry extension +!Cname hold-instruction-code +id-ce 23 : holdInstructionCode : Hold Instruction Code +!Alias holdInstruction X9-57 2 +!Cname hold-instruction-none +holdInstruction 1 : holdInstructionNone : Hold Instruction None +!Cname hold-instruction-call-issuer +holdInstruction 2 : holdInstructionCallIssuer : Hold Instruction Call Issuer +!Cname hold-instruction-reject +holdInstruction 3 : holdInstructionReject : Hold Instruction Reject diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509v3/ext_dat.h index 62e80535b9..a6166f5745 100644 --- a/crypto/x509v3/ext_dat.h +++ b/crypto/x509v3/ext_dat.h @@ -60,9 +60,10 @@ extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info; extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; -extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_cpols, v3_crld; +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate, v3_cpols, v3_crld; extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern X509V3_EXT_METHOD v3_crl_hold; /* This table will be searched using OBJ_bsearch so it *must* kept in * order of the ext_nid values. @@ -89,6 +90,7 @@ static X509V3_EXT_METHOD *standard_exts[] = { &v3_crld, &v3_ext_ku, &v3_crl_reason, +&v3_crl_invdate, &v3_sxnet, &v3_info, &v3_ocsp_nonce, @@ -96,7 +98,8 @@ static X509V3_EXT_METHOD *standard_exts[] = { &v3_ocsp_accresp, &v3_ocsp_nocheck, &v3_ocsp_acutoff, -&v3_ocsp_serviceloc +&v3_ocsp_serviceloc, +&v3_crl_hold }; /* Number of standard extensions */ diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c index d8301a67bd..9ea59fb8f9 100644 --- a/crypto/x509v3/v3_lib.c +++ b/crypto/x509v3/v3_lib.c @@ -276,7 +276,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, if(!ext) { X509V3err(X509V3_F_X509V3_ADD_I2D, X509V3_R_ERROR_CREATING_EXTENSION); - return -1; + return 0; } /* If extension exists replace it.. */ diff --git a/crypto/x509v3/v3_ocsp.c b/crypto/x509v3/v3_ocsp.c index d21b6fbedb..c3e553afee 100644 --- a/crypto/x509v3/v3_ocsp.c +++ b/crypto/x509v3/v3_ocsp.c @@ -63,11 +63,12 @@ #include #include -/* OCSP extensions. +/* OCSP extensions and a couple of CRL entry extensions */ static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); +static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent); static void *ocsp_nonce_new(void); static int i2d_ocsp_nonce(void *a, unsigned char **pp); @@ -97,6 +98,24 @@ X509V3_EXT_METHOD v3_ocsp_acutoff = { NULL }; +X509V3_EXT_METHOD v3_crl_invdate = { + NID_invalidity_date, 0, &ASN1_GENERALIZEDTIME_it, + 0,0,0,0, + 0,0, + 0,0, + i2r_ocsp_acutoff,0, + NULL +}; + +X509V3_EXT_METHOD v3_crl_hold = { + NID_hold_instruction_code, 0, &ASN1_OBJECT_it, + 0,0,0,0, + 0,0, + 0,0, + i2r_object,0, + NULL +}; + X509V3_EXT_METHOD v3_ocsp_nonce = { NID_id_pkix_OCSP_Nonce, 0, NULL, ocsp_nonce_new, @@ -161,6 +180,13 @@ static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, in } +static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) +{ + if (!BIO_printf(bp, "%*s", ind, "")) return 0; + if(!i2a_ASN1_OBJECT(bp, oid)) return 0; + return 1; +} + /* OCSP nonce. This is needs special treatment because it doesn't have * an ASN1 encoding at all: it just contains arbitrary data. */