From 87c49f622e7fe9d93b3ab87b1edd5faa32fa6e74 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 9 Aug 1999 22:38:05 +0000 Subject: [PATCH] Support for parsing of certificate extensions in PKCS#10 requests: these are used by things like Xenroll. Also include documentation for extendedKeyUsage extension. --- CHANGES | 6 +++++ STATUS | 4 +-- crypto/asn1/t_req.c | 27 +++++++++++++++++++ crypto/asn1/t_x509.c | 4 --- crypto/objects/objects.h | 12 +++++++++ crypto/x509/x509.h | 4 +++ crypto/x509/x509_req.c | 56 ++++++++++++++++++++++++++++++++++++++++ doc/openssl.txt | 32 ++++++++++++++++++++++- 8 files changed, 138 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 300da0d773..33130ff462 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,12 @@ 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] diff --git a/STATUS b/STATUS index d67c128b4f..4d5343b8f2 100644 --- a/STATUS +++ b/STATUS @@ -1,6 +1,6 @@ OpenSSL STATUS Last modified at - ______________ $Date: 1999/08/09 11:14:06 $ + ______________ $Date: 1999/08/09 22:37:59 $ DEVELOPMENT STATE @@ -15,7 +15,6 @@ AVAILABLE PATCHES - o OCSP (titchenert@certco.com) 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). + 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 diff --git a/crypto/asn1/t_req.c b/crypto/asn1/t_req.c index bdd749436a..6049909a02 100644 --- a/crypto/asn1/t_req.c +++ b/crypto/asn1/t_req.c @@ -62,6 +62,7 @@ #include #include #include +#include #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; + STACK_OF(X509_EXTENSION) *exts; 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); + 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) @@ -201,6 +205,29 @@ get_next: } } + exts = X509_REQ_get_extensions(x); + if(exts) { + BIO_printf(bp,"%8sRequested Extensions:\n",""); + for (i=0; ivalue); + } + 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)); diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c index 42f4d498cf..80cf37bf04 100644 --- a/crypto/asn1/t_x509.c +++ b/crypto/asn1/t_x509.c @@ -188,11 +188,7 @@ int X509_print(BIO *bp, X509 *x) BIO_printf(bp,"%8sX509v3 extensions:\n",""); for (i=0; i #include diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 35f9484f8b..80ca680594 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -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_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); diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c index 2ef94decd1..6544f03f2c 100644 --- a/crypto/x509/x509_req.c +++ b/crypto/x509/x509_req.c @@ -113,3 +113,59 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) 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); +} diff --git a/doc/openssl.txt b/doc/openssl.txt index 91b85e5f14..2f50038d17 100644 --- a/doc/openssl.txt +++ b/doc/openssl.txt @@ -188,7 +188,7 @@ email.1=steve@here 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 @@ -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. +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 -- 2.25.1