aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2001-02-16 01:35:44 +0000
committerDr. Stephen Henson <steve@openssl.org>2001-02-16 01:35:44 +0000
commita6b7ffddac43c0805d02e7236034308f39bcd183 (patch)
treeb2644cd3df4422d7981dafd66db1a529c9cc66d6
parentf30d34f3a8f6dbdf33d01967e2671bfa90552728 (diff)
downloadopenssl-a6b7ffddac43c0805d02e7236034308f39bcd183.tar.gz
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.
-rw-r--r--CHANGES5
-rw-r--r--apps/ca.c324
-rw-r--r--crypto/asn1/asn1.h2
-rw-r--r--crypto/asn1/asn1t.h1
-rw-r--r--crypto/asn1/tasn_new.c7
-rw-r--r--crypto/objects/obj_dat.h34
-rw-r--r--crypto/objects/obj_mac.h22
-rw-r--r--crypto/objects/obj_mac.num4
-rw-r--r--crypto/objects/objects.txt10
-rw-r--r--crypto/x509v3/ext_dat.h7
-rw-r--r--crypto/x509v3/v3_lib.c2
-rw-r--r--crypto/x509v3/v3_ocsp.c28
12 files changed, 415 insertions, 31 deletions
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 <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
+#include <openssl/ocsp.h>
#include <openssl/pem.h>
#include <openssl/engine.h>
@@ -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 <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.
*/