Support for parsing of certificate extensions in PKCS#10 requests: these are
authorDr. Stephen Henson <steve@openssl.org>
Mon, 9 Aug 1999 22:38:05 +0000 (22:38 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 9 Aug 1999 22:38:05 +0000 (22:38 +0000)
used by things like Xenroll. Also include documentation for extendedKeyUsage
extension.

CHANGES
STATUS
crypto/asn1/t_req.c
crypto/asn1/t_x509.c
crypto/objects/objects.h
crypto/x509/x509.h
crypto/x509/x509_req.c
doc/openssl.txt

diff --git a/CHANGES b/CHANGES
index 300da0d7732e52287f365a96eebf73f69312edca..33130ff46243760f2456219d76b4729bad29752e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Initial support for certificate extension requests, these are included
+     in things like Xenroll certificate requests. They will later be used to
+     allow PKCS#10 requests to include a list of "requested extensions" which
+     can be added.
+     [Steve Henson]
+
   *) -crlf option to s_client and s_server for sending newlines as
      CRLF (as required by many protocols).
      [Bodo Moeller]
   *) -crlf option to s_client and s_server for sending newlines as
      CRLF (as required by many protocols).
      [Bodo Moeller]
diff --git a/STATUS b/STATUS
index d67c128b4f72e247c743e8943a3bfd12c3f3960c..4d5343b8f2948c6731565071566f11ef5b59b3c9 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,6 +1,6 @@
 
   OpenSSL STATUS                           Last modified at
 
   OpenSSL STATUS                           Last modified at
-  ______________                           $Date: 1999/08/09 11:14:06 $
+  ______________                           $Date: 1999/08/09 22:37:59 $
 
   DEVELOPMENT STATE
 
 
   DEVELOPMENT STATE
 
@@ -15,7 +15,6 @@
 
   AVAILABLE PATCHES
 
 
   AVAILABLE PATCHES
 
-    o OCSP (titchenert@certco.com) 
     o getenv in ca.c and x509_def.c (jaltman@watsun.cc.columbia.edu)
 
   IN PROGRESS
     o getenv in ca.c and x509_def.c (jaltman@watsun.cc.columbia.edu)
 
   IN PROGRESS
@@ -24,6 +23,7 @@
         Proper (or at least usable) certificate chain verification.
        Private key, certificate and CRL API and implementation.
        Checking and bugfixing PKCS#7 (S/MIME code).
         Proper (or at least usable) certificate chain verification.
        Private key, certificate and CRL API and implementation.
        Checking and bugfixing PKCS#7 (S/MIME code).
+        Various X509 issues: character sets, certificate request extensions.
 
     o Mark is currently working on:
         Folding in any changes that are in the C2Net code base that were
 
     o Mark is currently working on:
         Folding in any changes that are in the C2Net code base that were
index bdd749436ab9c0d1bb86ba2766c816b674672220..6049909a02f4dca8f66d86e33199f4cd066de25a 100644 (file)
@@ -62,6 +62,7 @@
 #include <openssl/bn.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/bn.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 #ifndef NO_FP_API
 int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
 
 #ifndef NO_FP_API
 int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
@@ -90,6 +91,7 @@ int X509_REQ_print(BIO *bp, X509_REQ *x)
        X509_REQ_INFO *ri;
        EVP_PKEY *pkey;
        STACK_OF(X509_ATTRIBUTE) *sk;
        X509_REQ_INFO *ri;
        EVP_PKEY *pkey;
        STACK_OF(X509_ATTRIBUTE) *sk;
+       STACK_OF(X509_EXTENSION) *exts;
        char str[128];
 
        ri=x->req_info;
        char str[128];
 
        ri=x->req_info;
@@ -161,6 +163,8 @@ int X509_REQ_print(BIO *bp, X509_REQ *x)
                        int j,type=0,count=1,ii=0;
 
                        a=sk_X509_ATTRIBUTE_value(sk,i);
                        int j,type=0,count=1,ii=0;
 
                        a=sk_X509_ATTRIBUTE_value(sk,i);
+                       if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
+                                                               continue;
                        sprintf(str,"%12s","");
                        if (BIO_puts(bp,str) <= 0) goto err;
                        if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
                        sprintf(str,"%12s","");
                        if (BIO_puts(bp,str) <= 0) goto err;
                        if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
@@ -201,6 +205,29 @@ get_next:
                        }
                }
 
                        }
                }
 
+       exts = X509_REQ_get_extensions(x);
+       if(exts) {
+               BIO_printf(bp,"%8sRequested Extensions:\n","");
+               for (i=0; i<sk_X509_EXTENSION_num(exts); i++) {
+                       ASN1_OBJECT *obj;
+                       X509_EXTENSION *ex;
+                       int j;
+                       ex=sk_X509_EXTENSION_value(exts, i);
+                       if (BIO_printf(bp,"%12s","") <= 0) goto err;
+                       obj=X509_EXTENSION_get_object(ex);
+                       i2a_ASN1_OBJECT(bp,obj);
+                       j=X509_EXTENSION_get_critical(ex);
+                       if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0)
+                               goto err;
+                       if(!X509V3_EXT_print(bp, ex, 0, 16)) {
+                               BIO_printf(bp, "%16s", "");
+                               ASN1_OCTET_STRING_print(bp,ex->value);
+                       }
+                       if (BIO_write(bp,"\n",1) <= 0) goto err;
+               }
+               sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+       }
+
        i=OBJ_obj2nid(x->sig_alg->algorithm);
        sprintf(str,"%4sSignature Algorithm: %s","",
                (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
        i=OBJ_obj2nid(x->sig_alg->algorithm);
        sprintf(str,"%4sSignature Algorithm: %s","",
                (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
index 42f4d498cfa5d788b1a417a51946936a11c38fe3..80cf37bf0499d3a4443929a9e9a920a18757c345 100644 (file)
@@ -188,11 +188,7 @@ int X509_print(BIO *bp, X509 *x)
                BIO_printf(bp,"%8sX509v3 extensions:\n","");
                for (i=0; i<n; i++)
                        {
                BIO_printf(bp,"%8sX509v3 extensions:\n","");
                for (i=0; i<n; i++)
                        {
-#if 0
-                       int data_type,pack_type;
-#endif
                        ASN1_OBJECT *obj;
                        ASN1_OBJECT *obj;
-
                        ex=X509_get_ext(x,i);
                        if (BIO_printf(bp,"%12s","") <= 0) goto err;
                        obj=X509_EXTENSION_get_object(ex);
                        ex=X509_get_ext(x,i);
                        if (BIO_printf(bp,"%12s","") <= 0) goto err;
                        obj=X509_EXTENSION_get_object(ex);
index d03748e0228af03f211a2d176d32cfe04aeb6207..f7cfe1c92c6129618a8093043c7ad3bcfa28187f 100644 (file)
@@ -890,6 +890,18 @@ extern "C" {
 #define NID_pbeWithSHA1AndDES_CBC      170
 #define OBJ_pbeWithSHA1AndDES_CBC      OBJ_pkcs,5L,10L
 
 #define NID_pbeWithSHA1AndDES_CBC      170
 #define OBJ_pbeWithSHA1AndDES_CBC      OBJ_pkcs,5L,10L
 
+/* Extension request OIDs */
+
+#define LN_ms_ext_req                  "Microsoft Extension Request"
+#define SN_ms_ext_req                  "msExtReq"
+#define NID_ms_ext_req                 171
+#define OBJ_ms_ext_req                 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req                     "Extension Request"
+#define SN_ext_req                     "extReq"
+#define NID_ext_req                    172
+#define OBJ_ext_req                    OBJ_pkcs9,14L
+
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 
index 35f9484f8b9833f8a5386c482a75e0a228e327b5..80ca680594f5060255d01c610ecbd3eaeef62356 100644 (file)
@@ -787,6 +787,10 @@ int                X509_REQ_set_version(X509_REQ *x,long version);
 int            X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
 int            X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
 EVP_PKEY *     X509_REQ_get_pubkey(X509_REQ *req);
 int            X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
 int            X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
 EVP_PKEY *     X509_REQ_get_pubkey(X509_REQ *req);
+int            X509_REQ_extension_nid(int nid);
+int *          X509_REQ_get_extesion_nids(void);
+void           X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
 
 int            X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
 
 
 int            X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
 
index 2ef94decd1446107576699d394f3cb88b5100993..6544f03f2ceb5f6272b29a5ca269f0dbf716279d 100644 (file)
@@ -113,3 +113,59 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
        return(X509_PUBKEY_get(req->req_info->pubkey));
        }
 
        return(X509_PUBKEY_get(req->req_info->pubkey));
        }
 
+/* It seems several organisations had the same idea of including a list of
+ * extensions in a certificate request. There are at least two OIDs that are
+ * used and there may be more: so the list is configurable.
+ */
+
+static int ext_nid_list[] = { NID_ms_ext_req, NID_ext_req, NID_undef};
+
+static int *ext_nids = ext_nid_list;
+
+int X509_REQ_extension_nid(int req_nid)
+{
+       int i, nid;
+       for(i = 0; ; i++) {
+               nid = ext_nids[i];
+               if(nid == NID_undef) return 0;
+               else if (req_nid == nid) return 1;
+       }
+}
+
+int *X509_REQ_get_extesion_nids(void)
+{
+       return ext_nids;
+}
+       
+void X509_REQ_set_extension_nids(int *nids)
+{
+       ext_nids = nids;
+}
+
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
+{
+       X509_ATTRIBUTE *attr;
+       STACK_OF(X509_ATTRIBUTE) *sk;
+       ASN1_TYPE *ext = NULL;
+       int i;
+       unsigned char *p;
+       if ((req == NULL) || (req->req_info == NULL))
+               return(NULL);
+       sk=req->req_info->attributes;
+        if (!sk) return NULL;
+       for(i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+               attr = sk_X509_ATTRIBUTE_value(sk, i);
+               if(X509_REQ_extension_nid(OBJ_obj2nid(attr->object))) {
+                       if(attr->set && sk_ASN1_TYPE_num(attr->value.set))
+                               ext = sk_ASN1_TYPE_value(attr->value.set, 0);
+                       else ext = attr->value.single;
+                       break;
+               }
+       }
+       if(!ext || (ext->type != V_ASN1_SEQUENCE)) return NULL;
+       p = ext->value.sequence->data;
+       return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p,
+                       ext->value.sequence->length,
+                       d2i_X509_EXTENSION, X509_EXTENSION_free,
+                       V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+}
index 91b85e5f14cb37c75fe0639b99599ef2e413972b..2f50038d1770636d9416cc54af609152b263cb6b 100644 (file)
@@ -188,7 +188,7 @@ email.1=steve@here
 email.2=steve@there
 
 This is because the configuration file code cannot handle the same name
 email.2=steve@there
 
 This is because the configuration file code cannot handle the same name
-occurring twice in the same extension.
+occurring twice in the same section.
 
 The syntax of raw extensions is governed by the extension code: it can
 for example contain data in multiple sections. The correct syntax to
 
 The syntax of raw extensions is governed by the extension code: it can
 for example contain data in multiple sections. The correct syntax to
@@ -315,6 +315,36 @@ TRUE. An end user certificate MUST NOT have the CA value set to true.
 According to PKIX recommendations it should exclude the extension entirely,
 however some software may require CA set to FALSE for end entity certificates.
 
 According to PKIX recommendations it should exclude the extension entirely,
 however some software may require CA set to FALSE for end entity certificates.
 
+Extended Key Usage.
+
+This extensions consists of a list of usages.
+
+These can either be object short names of the dotted numerical form of OIDs.
+While any OID can be used only certain values make sense. In partiular the
+following PKIX, NS and MS values are meaningful:
+
+Value                  Meaning
+-----                  -------
+serverAuth             SSL/TLS Web Server Authentication.
+clientAuth             SSL/TLS Web Client Authentication.
+codeSigning            Code signing.
+emailProtection                E-mail Protection (S/MIME).
+timeStamping           Trusted Timestamping
+msCodeInd              Microsoft Individual Code Signing (authenticode)
+msCodeCom              Microsoft Commercial Code Signing (authenticode)
+msCTLSign              Microsoft Trust List Signing
+msSGC                  Microsoft Server Gated Crypto
+msEFS                  Microsoft Encrypted File System
+nsSGC                  Netscape Server Gated Crypto
+
+For example, under IE5 a CA can be used for any purpose: by including a list
+of the above usages the CA can be restricted to only authorised uses.
+
+Note: software packages may place additional interpretations on certificate 
+use, in particular some usages may only work for selected CAs. Don't for example
+expect just including msSGC or nsSGC will automatically mean that a certificate
+can be used for SGC ("step up" encryption) otherwise anyone could use it.
+
 Subject Key Identifier.
 
 This is really a string extension and can take two possible values. Either
 Subject Key Identifier.
 
 This is really a string extension and can take two possible values. Either