New options to 'ca' utility to support CRL entry extensions.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 16 Feb 2001 01:35:44 +0000 (01:35 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 16 Feb 2001 01:35:44 +0000 (01:35 +0000)
Add revelant new X509V3 extensions.

Add OIDs.

Fix ASN1 memory leak code to pop info if external allocation used.

12 files changed:
CHANGES
apps/ca.c
crypto/asn1/asn1.h
crypto/asn1/asn1t.h
crypto/asn1/tasn_new.c
crypto/objects/obj_dat.h
crypto/objects/obj_mac.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
crypto/x509v3/ext_dat.h
crypto/x509v3/v3_lib.c
crypto/x509v3/v3_ocsp.c

diff --git a/CHANGES b/CHANGES
index ca0ecc3..4e23d17 100644 (file)
--- 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]
 
index b84e842..e0349a7 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -74,6 +74,7 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
+#include <openssl/ocsp.h>
 #include <openssl/pem.h>
 #include <openssl/engine.h>
 
 #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;
+       }
index 6ee0871..51d2e16 100644 (file)
@@ -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)
 
index 5e6efe2..c854c96 100644 (file)
@@ -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;
index 3371dd1..798f9bf 100644 (file)
@@ -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);
index 163ab03..e50f045 100644 (file)
  * 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 */
index 616c980..c334ba6 100644 (file)
 #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
+
index 543b748..70a5730 100644 (file)
@@ -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
index d3af5f2..1497684 100644 (file)
@@ -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
index 62e8053..a6166f5 100644 (file)
 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 */
index d8301a6..9ea59fb 100644 (file)
@@ -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.. */
index d21b6fb..c3e553a 100644 (file)
 #include <openssl/ocsp.h>
 #include <openssl/x509v3.h>
 
-/* 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.
  */