Merge RFC3820 source into mainstream 0.9.7-stable.
authorRichard Levitte <levitte@openssl.org>
Mon, 11 Apr 2005 15:03:37 +0000 (15:03 +0000)
committerRichard Levitte <levitte@openssl.org>
Mon, 11 Apr 2005 15:03:37 +0000 (15:03 +0000)
25 files changed:
CHANGES
STATUS
apps/openssl-vms.cnf
apps/openssl.cnf
crypto/crypto-lib.com
crypto/objects/obj_dat.h
crypto/objects/obj_mac.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
crypto/x509/x509_txt.c
crypto/x509/x509_vfy.c
crypto/x509/x509_vfy.h
crypto/x509v3/Makefile
crypto/x509v3/ext_dat.h
crypto/x509v3/v3_purp.c
crypto/x509v3/v3err.c
crypto/x509v3/x509v3.h
doc/standards.txt
ssl/ssltest.c
test/CAss.cnf
test/Makefile
test/Uss.cnf
test/testss
util/libeay.num
util/mkerr.pl

diff --git a/CHANGES b/CHANGES
index b4c019f12137cde2590baeaef0a74368ce366d1d..227f50818816456a084883f7be90e3354a8d4cab 100644 (file)
--- a/CHANGES
+++ b/CHANGES
   *) Undo Cygwin change.
      [Ulf Möller]
 
+  *) Added support for proxy certificates according to RFC 3820.
+     Because they may be a security thread to unaware applications,
+     they must be explicitely allowed in run-time.  See
+     docs/HOWTO/proxy_certificates.txt for further information.
+     [Richard Levitte]
+
  Changes between 0.9.7e and 0.9.7f  [22 Mar 2005]
 
   *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
diff --git a/STATUS b/STATUS
index e849945dcd8e81934dab6bd27efbbe9443583787..467ca197142bd4cf10ff5ddc86b4cb73365d4eec 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,6 +1,6 @@
 
   OpenSSL STATUS                           Last modified at
-  ______________                           $Date: 2005/03/22 18:17:22 $
+  ______________                           $Date: 2005/04/11 15:03:37 $
 
   DEVELOPMENT STATE
 
index d8bc419de563aaebe5cb640742a202cc04756cb7..878467ce9828f4ab1c26ee1555d9abb76d14101c 100644 (file)
@@ -258,3 +258,56 @@ basicConstraints = CA:true
 
 # issuerAltName=issuer:copy
 authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType                   = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment                      = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl             = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
index af688a426036927e90c19db43725f9452289b9e6..4c1d595b0a0a3ca5eeca8d954fa3d04e6a51c643 100644 (file)
@@ -258,3 +258,56 @@ basicConstraints = CA:true
 
 # issuerAltName=issuer:copy
 authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType                   = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment                      = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl             = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
index 4d802fe69c1c2e1be546c3251e4f00cb16babb5b..c044ce0099df771e05a41e485614f24f8a223576 100644 (file)
@@ -247,7 +247,7 @@ $ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
 $ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
        "v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
        "v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
-       "v3_ocsp,v3_akeya"
+       "v3_ocsp,v3_akeya,v3_pcia,v3_pci"
 $ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
 $ LIB_TXT_DB = "txt_db"
 $ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
index ae50a72b9a8b3add98f82fd4cf5b110d44ebecd6..87851270555de35a190edf4aabb108ccb02e9502 100644 (file)
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 662
-#define NUM_SN 655
-#define NUM_LN 655
-#define NUM_OBJ 619
+#define NUM_NID 668
+#define NUM_SN 660
+#define NUM_LN 660
+#define NUM_OBJ 624
 
-static unsigned char lvalues[4461]={
+static unsigned char lvalues[4500]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -687,6 +687,11 @@ static unsigned char lvalues[4461]={
 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4444] OBJ_ms_upn */
 0x55,0x04,0x09,                              /* [4454] OBJ_streetAddress */
 0x55,0x04,0x11,                              /* [4457] OBJ_postalCode */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4460] OBJ_id_ppl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4467] OBJ_proxyCertInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4475] OBJ_id_ppl_anyLanguage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4483] OBJ_id_ppl_inheritAll */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4491] OBJ_Independent */
 };
 
 static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -1742,6 +1747,15 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
 {"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL},
 {"streetAddress","streetAddress",NID_streetAddress,3,&(lvalues[4454]),0},
 {"postalCode","postalCode",NID_postalCode,3,&(lvalues[4457]),0},
+{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4460]),0},
+{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
+       &(lvalues[4467]),0},
+{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
+       &(lvalues[4475]),0},
+{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
+       &(lvalues[4483]),0},
+{NULL,NULL,NID_undef,0,NULL},
+{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4491]),0},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -2046,6 +2060,10 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[271]),/* "id-pkix1-explicit-93" */
 &(nid_objs[270]),/* "id-pkix1-implicit-88" */
 &(nid_objs[272]),/* "id-pkix1-implicit-93" */
+&(nid_objs[662]),/* "id-ppl" */
+&(nid_objs[664]),/* "id-ppl-anyLanguage" */
+&(nid_objs[667]),/* "id-ppl-independent" */
+&(nid_objs[665]),/* "id-ppl-inheritAll" */
 &(nid_objs[267]),/* "id-qcs" */
 &(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */
 &(nid_objs[259]),/* "id-qt" */
@@ -2221,6 +2239,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[415]),/* "prime256v1" */
 &(nid_objs[385]),/* "private" */
 &(nid_objs[84]),/* "privateKeyUsagePeriod" */
+&(nid_objs[663]),/* "proxyCertInfo" */
 &(nid_objs[510]),/* "pseudonym" */
 &(nid_objs[435]),/* "pss" */
 &(nid_objs[286]),/* "qcStatements" */
@@ -2406,6 +2425,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[363]),/* "AD Time Stamping" */
 &(nid_objs[405]),/* "ANSI X9.62" */
 &(nid_objs[368]),/* "Acceptable OCSP Responses" */
+&(nid_objs[664]),/* "Any language" */
 &(nid_objs[177]),/* "Authority Information Access" */
 &(nid_objs[365]),/* "Basic OCSP Response" */
 &(nid_objs[285]),/* "Biometric Info" */
@@ -2428,6 +2448,8 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[296]),/* "IPSec User" */
 &(nid_objs[182]),/* "ISO Member Body" */
 &(nid_objs[183]),/* "ISO US Member Body" */
+&(nid_objs[667]),/* "Independent" */
+&(nid_objs[665]),/* "Inherit all" */
 &(nid_objs[142]),/* "Invalidity Date" */
 &(nid_objs[504]),/* "MIME MHS" */
 &(nid_objs[388]),/* "Mail" */
@@ -2468,6 +2490,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[164]),/* "Policy Qualifier CPS" */
 &(nid_objs[165]),/* "Policy Qualifier User Notice" */
 &(nid_objs[385]),/* "Private" */
+&(nid_objs[663]),/* "Proxy Certificate Information" */
 &(nid_objs[ 1]),/* "RSA Data Security, Inc." */
 &(nid_objs[ 2]),/* "RSA Data Security, Inc. PKCS" */
 &(nid_objs[188]),/* "S/MIME" */
@@ -2704,6 +2727,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[271]),/* "id-pkix1-explicit-93" */
 &(nid_objs[270]),/* "id-pkix1-implicit-88" */
 &(nid_objs[272]),/* "id-pkix1-implicit-93" */
+&(nid_objs[662]),/* "id-ppl" */
 &(nid_objs[267]),/* "id-qcs" */
 &(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */
 &(nid_objs[259]),/* "id-qt" */
@@ -3310,6 +3334,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[266]),/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
 &(nid_objs[267]),/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
 &(nid_objs[268]),/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
+&(nid_objs[662]),/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
 &(nid_objs[176]),/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
 &(nid_objs[507]),/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
 &(nid_objs[508]),/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
@@ -3363,6 +3388,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[292]),/* OBJ_sbqp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
 &(nid_objs[397]),/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
 &(nid_objs[398]),/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
+&(nid_objs[663]),/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
 &(nid_objs[164]),/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
 &(nid_objs[165]),/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
 &(nid_objs[293]),/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
@@ -3433,6 +3459,9 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[360]),/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
 &(nid_objs[361]),/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
 &(nid_objs[362]),/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
+&(nid_objs[664]),/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
+&(nid_objs[665]),/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
+&(nid_objs[667]),/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
 &(nid_objs[178]),/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
 &(nid_objs[179]),/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
 &(nid_objs[363]),/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
index b1a3c8a85787f7b0f77e42c877ba9c18cf87c182..d28894cf418bb0b443dacf456bac2b8ba864cb1d 100644 (file)
 #define NID_id_cct             268
 #define OBJ_id_cct             OBJ_id_pkix,12L
 
+#define SN_id_ppl              "id-ppl"
+#define NID_id_ppl             662
+#define OBJ_id_ppl             OBJ_id_pkix,21L
+
 #define SN_id_ad               "id-ad"
 #define NID_id_ad              176
 #define OBJ_id_ad              OBJ_id_pkix,48L
 #define NID_sinfo_access               398
 #define OBJ_sinfo_access               OBJ_id_pe,11L
 
+#define SN_proxyCertInfo               "proxyCertInfo"
+#define LN_proxyCertInfo               "Proxy Certificate Information"
+#define NID_proxyCertInfo              663
+#define OBJ_proxyCertInfo              OBJ_id_pe,14L
+
 #define SN_id_qt_cps           "id-qt-cps"
 #define LN_id_qt_cps           "Policy Qualifier CPS"
 #define NID_id_qt_cps          164
 #define NID_id_cct_PKIResponse         362
 #define OBJ_id_cct_PKIResponse         OBJ_id_cct,3L
 
+#define SN_id_ppl_anyLanguage          "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage          "Any language"
+#define NID_id_ppl_anyLanguage         664
+#define OBJ_id_ppl_anyLanguage         OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll           "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll           "Inherit all"
+#define NID_id_ppl_inheritAll          665
+#define OBJ_id_ppl_inheritAll          OBJ_id_ppl,1L
+
+#define SN_Independent         "id-ppl-independent"
+#define LN_Independent         "Independent"
+#define NID_Independent                667
+#define OBJ_Independent                OBJ_id_ppl,2L
+
 #define SN_ad_OCSP             "OCSP"
 #define LN_ad_OCSP             "OCSP"
 #define NID_ad_OCSP            178
index f808d964420c390fa496931695cee75af0495fbe..0e64a929bab3435be1124548981d651498d95ec7 100644 (file)
@@ -659,3 +659,9 @@ des_ede3_cfb1               658
 des_ede3_cfb8          659
 streetAddress          660
 postalCode             661
+id_ppl         662
+proxyCertInfo          663
+id_ppl_anyLanguage             664
+id_ppl_inheritAll              665
+id_ppl_independent             666
+Independent            667
index 10d811c37795bc8ccbdb0fbf7e75ec8da1e95e4a..50e9031e61ebc5f79179e923d713bae75761dbfa 100644 (file)
@@ -312,6 +312,7 @@ id-pkix 9           : id-pda
 id-pkix 10             : id-aca
 id-pkix 11             : id-qcs
 id-pkix 12             : id-cct
+id-pkix 21             : id-ppl
 id-pkix 48             : id-ad
 
 # PKIX Modules
@@ -346,6 +347,7 @@ id-pe 9                     : sbqp-routerIdentifier
 id-pe 10               : ac-proxying
 !Cname sinfo-access
 id-pe 11               : subjectInfoAccess     : Subject Information Access
+id-pe 14               : proxyCertInfo         : Proxy Certificate Information
 
 # PKIX policyQualifiers for Internet policy qualifiers
 id-qt 1                        : id-qt-cps             : Policy Qualifier CPS
@@ -461,6 +463,11 @@ id-cct 1           : id-cct-crs
 id-cct 2               : id-cct-PKIData
 id-cct 3               : id-cct-PKIResponse
 
+# Predefined Proxy Certificate policy languages
+id-ppl 0               : id-ppl-anyLanguage    : Any language
+id-ppl 1               : id-ppl-inheritAll     : Inherit all
+id-ppl 2               : id-ppl-independent    : Independent
+
 # access descriptors for authority info access extension
 !Cname ad-OCSP
 id-ad 1                        : OCSP                  : OCSP
index b8f5bc0cd71ca283d09a111970dd50c7fdef80e3..f19e66a238a92786239f2fc5de6e2f3b344ad4f4 100644 (file)
@@ -126,6 +126,10 @@ const char *X509_verify_cert_error_string(long n)
                return ("invalid non-CA certificate (has CA markings)");
        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
                return ("path length constraint exceeded");
+       case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+               return("proxy path length constraint exceeded");
+       case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+               return("proxy cerificates not allowed, please set the appropriate flag");
        case X509_V_ERR_INVALID_PURPOSE:
                return ("unsupported certificate purpose");
        case X509_V_ERR_CERT_UNTRUSTED:
@@ -142,19 +146,16 @@ const char *X509_verify_cert_error_string(long n)
                return("authority and issuer serial number mismatch");
        case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
                return("key usage does not include certificate signing");
-
        case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
                return("unable to get CRL issuer certificate");
-
        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
                return("unhandled critical extension");
-
        case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
                return("key usage does not include CRL signing");
-
+       case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+               return("key usage does not include digital signature");
        case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
                return("unhandled critical CRL extension");
-
        default:
                BIO_snprintf(buf,sizeof buf,"error number %ld",n);
                return(buf);
index e60055c342ca8fc4c92521a658847fdc17a6cf47..e43c861ee77e1138bf43d7b9e428d4dc8e34f88c 100644 (file)
@@ -379,6 +379,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
        int i, ok=0, must_be_ca;
        X509 *x;
        int (*cb)();
+       int proxy_path_length = 0;
+       int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
        cb=ctx->verify_cb;
 
        /* must_be_ca can have 1 of 3 values:
@@ -390,6 +392,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
               all certificates in the chain except the leaf certificate.
        */
        must_be_ca = -1;
+
+       /* A hack to keep people who don't want to modify their software
+          happy */
+       if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+               allow_proxy_certs = 1;
+
        /* Check all untrusted certificates */
        for (i = 0; i < ctx->last_untrusted; i++)
                {
@@ -404,6 +412,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                        ok=cb(0,ctx);
                        if (!ok) goto end;
                        }
+               if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
+                       {
+                       ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+                       ctx->error_depth = i;
+                       ctx->current_cert = x;
+                       ok=cb(0,ctx);
+                       if (!ok) goto end;
+                       }
                ret = X509_check_ca(x);
                switch(must_be_ca)
                        {
@@ -462,7 +478,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                        }
                /* Check pathlen */
                if ((i > 1) && (x->ex_pathlen != -1)
-                          && (i > (x->ex_pathlen + 1)))
+                          && (i > (x->ex_pathlen + proxy_path_length + 1)))
                        {
                        ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
                        ctx->error_depth = i;
@@ -470,8 +486,32 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                        ok=cb(0,ctx);
                        if (!ok) goto end;
                        }
-               /* The next certificate must be a CA */
-               must_be_ca = 1;
+               /* If this certificate is a proxy certificate, the next
+                  certificate must be another proxy certificate or a EE
+                  certificate.  If not, the next certificate must be a
+                  CA certificate.  */
+               if (x->ex_flags & EXFLAG_PROXY)
+                       {
+                       PROXY_CERT_INFO_EXTENSION *pci =
+                               X509_get_ext_d2i(x, NID_proxyCertInfo,
+                                       NULL, NULL);
+                       if (pci->pcPathLengthConstraint &&
+                               ASN1_INTEGER_get(pci->pcPathLengthConstraint)
+                               < i)
+                               {
+                               PROXY_CERT_INFO_EXTENSION_free(pci);
+                               ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+                               ctx->error_depth = i;
+                               ctx->current_cert = x;
+                               ok=cb(0,ctx);
+                               if (!ok) goto end;
+                               }
+                       PROXY_CERT_INFO_EXTENSION_free(pci);
+                       proxy_path_length++;
+                       must_be_ca = 0;
+                       }
+               else
+                       must_be_ca = 1;
                }
        ok = 1;
  end:
@@ -835,6 +875,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
                        }
 
                /* The last error (if any) is still in the error value */
+               ctx->current_issuer=xi;
                ctx->current_cert=xs;
                ok=(*cb)(1,ctx);
                if (!ok) goto end;
index cb725b64d89c40668152244a14bcb3bd1b8d7aa6..7fd1f0bc4deb52734c6a7dee6a99547caa10bc98 100644 (file)
@@ -276,7 +276,7 @@ struct x509_store_ctx_st      /* X509_STORE_CTX */
 #define                X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
 #define                X509_V_ERR_CERT_SIGNATURE_FAILURE               7
 #define                X509_V_ERR_CRL_SIGNATURE_FAILURE                8
-#define                X509_V_ERR_CERT_NOT_YET_VALID                   9       
+#define                X509_V_ERR_CERT_NOT_YET_VALID                   9
 #define                X509_V_ERR_CERT_HAS_EXPIRED                     10
 #define                X509_V_ERR_CRL_NOT_YET_VALID                    11
 #define                X509_V_ERR_CRL_HAS_EXPIRED                      12
@@ -307,6 +307,9 @@ struct x509_store_ctx_st      /* X509_STORE_CTX */
 #define                X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
 #define                X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
 #define                X509_V_ERR_INVALID_NON_CA                       37
+#define                X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+#define                X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+#define                X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
 
 /* The application is not happy */
 #define                X509_V_ERR_APPLICATION_VERIFICATION             50
@@ -325,6 +328,8 @@ struct x509_store_ctx_st      /* X509_STORE_CTX */
 #define        X509_V_FLAG_IGNORE_CRITICAL             0x10
 /* Disable workarounds for broken certificates */
 #define        X509_V_FLAG_X509_STRICT                 0x20
+/* Enable proxy certificate validation */
+#define        X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
 
 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
             X509_NAME *name);
index 5aeffc7948f1ddd685836c3038b265c912128551..ed2f91cbb3f91f1a770909612f0e72e7e1fedbd0 100644 (file)
@@ -25,11 +25,11 @@ LIB=$(TOP)/libcrypto.a
 LIBSRC=        v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \
 v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \
 v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \
-v3_ocsp.c v3_akeya.c
+v3_ocsp.c v3_akeya.c v3_pcia.c v3_pci.c
 LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \
 v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \
 v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \
-v3_ocsp.o v3_akeya.o
+v3_ocsp.o v3_akeya.o v3_pcia.o v3_pci.o
 
 SRC= $(LIBSRC)
 
@@ -444,6 +444,50 @@ v3_ocsp.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
 v3_ocsp.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
 v3_ocsp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
 v3_ocsp.o: ../cryptlib.h v3_ocsp.c
+v3_pci.o: ../../e_os.h ../../include/openssl/aes.h ../../include/openssl/asn1.h
+v3_pci.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+v3_pci.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+v3_pci.o: ../../include/openssl/cast.h ../../include/openssl/conf.h
+v3_pci.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+v3_pci.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
+v3_pci.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+v3_pci.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+v3_pci.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+v3_pci.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+v3_pci.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+v3_pci.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pci.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_pci.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_pci.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+v3_pci.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+v3_pci.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+v3_pci.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pci.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+v3_pci.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+v3_pci.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pci.o: ../cryptlib.h v3_pci.c
+v3_pcia.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+v3_pcia.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
+v3_pcia.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+v3_pcia.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+v3_pcia.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+v3_pcia.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+v3_pcia.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+v3_pcia.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
+v3_pcia.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+v3_pcia.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+v3_pcia.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+v3_pcia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_pcia.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_pcia.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_pcia.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+v3_pcia.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+v3_pcia.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+v3_pcia.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pcia.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+v3_pcia.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+v3_pcia.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pcia.o: v3_pcia.c
 v3_pku.o: ../../e_os.h ../../include/openssl/aes.h ../../include/openssl/asn1.h
 v3_pku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_pku.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
index 6fa3178e6e0a459ea70de6249ba2d2a6514b825e..d8328ac468c82f3c0eea279884cd8d525d315194 100644 (file)
@@ -64,7 +64,7 @@ extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
 extern X509V3_EXT_METHOD v3_delta_crl, 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;
+extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
 
 /* This table will be searched using OBJ_bsearch so it *must* kept in
  * order of the ext_nid values.
@@ -107,8 +107,9 @@ static X509V3_EXT_METHOD *standard_exts[] = {
 #endif
 &v3_sinfo,
 #ifndef OPENSSL_NO_OCSP
-&v3_crl_hold
+&v3_crl_hold,
 #endif
+&v3_pci,
 };
 
 /* Number of standard extensions */
index 3e94f77c793adbc523ef62f081a12e03d55a44a4..bbdf6da4937b8083bb38032635c3353175eaf59a 100644 (file)
@@ -285,7 +285,8 @@ int X509_supported_extension(X509_EXTENSION *ex)
                NID_key_usage,          /* 83 */
                NID_subject_alt_name,   /* 85 */
                NID_basic_constraints,  /* 87 */
-               NID_ext_key_usage       /* 126 */
+               NID_ext_key_usage,      /* 126 */
+               NID_proxyCertInfo       /* 661 */
        };
 
        int ex_nid;
@@ -306,6 +307,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
 static void x509v3_cache_extensions(X509 *x)
 {
        BASIC_CONSTRAINTS *bs;
+       PROXY_CERT_INFO_EXTENSION *pci;
        ASN1_BIT_STRING *usage;
        ASN1_BIT_STRING *ns;
        EXTENDED_KEY_USAGE *extusage;
@@ -334,6 +336,16 @@ static void x509v3_cache_extensions(X509 *x)
                BASIC_CONSTRAINTS_free(bs);
                x->ex_flags |= EXFLAG_BCONS;
        }
+       /* Handle proxy certificates */
+       if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+               if (x->ex_flags & EXFLAG_CA
+                   || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
+                   || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
+                       x->ex_flags |= EXFLAG_INVALID;
+               }
+               PROXY_CERT_INFO_EXTENSION_free(pci);
+               x->ex_flags |= EXFLAG_PROXY;
+       }
        /* Handle key usage */
        if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
                if(usage->length > 0) {
@@ -623,7 +635,13 @@ int X509_check_issued(X509 *issuer, X509 *subject)
                                return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
                }
        }
-       if(ku_reject(issuer, KU_KEY_CERT_SIGN)) return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+       if(subject->ex_flags & EXFLAG_PROXY)
+               {
+               if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
+                       return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+               }
+       else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
+               return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
        return X509_V_OK;
 }
 
index 000ddbc388fec318fb1abc618f18ab777dcc0580..2df0c3ef01dc4d6c40fee3b725dc2b4cffffc935 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/x509v3/v3err.c */
 /* ====================================================================
- * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -79,6 +79,7 @@ static ERR_STRING_DATA X509V3_str_functs[]=
 {ERR_PACK(0,X509V3_F_NREF_NOS,0),      "NREF_NOS"},
 {ERR_PACK(0,X509V3_F_POLICY_SECTION,0),        "POLICY_SECTION"},
 {ERR_PACK(0,X509V3_F_R2I_CERTPOL,0),   "R2I_CERTPOL"},
+{ERR_PACK(0,X509V3_F_R2I_PCI,0),       "R2I_PCI"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_IA5STRING,0),    "S2I_ASN1_IA5STRING"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_INTEGER,0),      "s2i_ASN1_INTEGER"},
 {ERR_PACK(0,X509V3_F_S2I_ASN1_OCTET_STRING,0), "s2i_ASN1_OCTET_STRING"},
@@ -129,6 +130,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"},
 {X509V3_R_EXTENSION_VALUE_ERROR          ,"extension value error"},
 {X509V3_R_ILLEGAL_HEX_DIGIT              ,"illegal hex digit"},
+{X509V3_R_INCORRECT_POLICY_SYNTAX_TAG    ,"incorrect policy syntax tag"},
 {X509V3_R_INVALID_BOOLEAN_STRING         ,"invalid boolean string"},
 {X509V3_R_INVALID_EXTENSION_STRING       ,"invalid extension string"},
 {X509V3_R_INVALID_NAME                   ,"invalid name"},
@@ -140,6 +142,8 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_INVALID_OBJECT_IDENTIFIER      ,"invalid object identifier"},
 {X509V3_R_INVALID_OPTION                 ,"invalid option"},
 {X509V3_R_INVALID_POLICY_IDENTIFIER      ,"invalid policy identifier"},
+{X509V3_R_INVALID_PROXY_POLICY_IDENTIFIER,"invalid proxy policy identifier"},
+{X509V3_R_INVALID_PROXY_POLICY_SETTING   ,"invalid proxy policy setting"},
 {X509V3_R_INVALID_PURPOSE                ,"invalid purpose"},
 {X509V3_R_INVALID_SECTION                ,"invalid section"},
 {X509V3_R_INVALID_SYNTAX                 ,"invalid syntax"},
@@ -150,9 +154,16 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_NO_ISSUER_CERTIFICATE          ,"no issuer certificate"},
 {X509V3_R_NO_ISSUER_DETAILS              ,"no issuer details"},
 {X509V3_R_NO_POLICY_IDENTIFIER           ,"no policy identifier"},
+{X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED,"no proxy cert policy language defined"},
 {X509V3_R_NO_PUBLIC_KEY                  ,"no public key"},
 {X509V3_R_NO_SUBJECT_DETAILS             ,"no subject details"},
 {X509V3_R_ODD_NUMBER_OF_DIGITS           ,"odd number of digits"},
+{X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED,"policy language alreadty defined"},
+{X509V3_R_POLICY_PATH_LENGTH             ,"policy path length"},
+{X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED,"policy path length alreadty defined"},
+{X509V3_R_POLICY_SYNTAX_NOT              ,"policy syntax not"},
+{X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED,"policy syntax not currently supported"},
+{X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY,"policy when proxy language requires no policy"},
 {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS   ,"unable to get issuer details"},
 {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID     ,"unable to get issuer keyid"},
 {X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT    ,"unknown bit string argument"},
index f220ca5e3e8318856d9f8c03a075ae75dbc37376..e6d91251c2a112d0283bcd86f8e3264f46850f55 100644 (file)
@@ -287,6 +287,23 @@ typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
 DECLARE_STACK_OF(POLICYINFO)
 DECLARE_ASN1_SET_OF(POLICYINFO)
 
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st
+       {
+       ASN1_OBJECT *policyLanguage;
+       ASN1_OCTET_STRING *policy;
+       } PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st
+       {
+       ASN1_INTEGER *pcPathLengthConstraint;
+       PROXY_POLICY *proxyPolicy;
+       } PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+
 #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
 ",name:", val->name, ",value:", val->value);
 
@@ -325,6 +342,7 @@ DECLARE_ASN1_SET_OF(POLICYINFO)
 #define EXFLAG_INVALID         0x80
 #define EXFLAG_SET             0x100
 #define EXFLAG_CRITICAL                0x200
+#define EXFLAG_PROXY           0x400
 
 #define KU_DIGITAL_SIGNATURE   0x0080
 #define KU_NON_REPUDIATION     0x0040
@@ -572,6 +590,7 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_F_NREF_NOS                               133
 #define X509V3_F_POLICY_SECTION                                 131
 #define X509V3_F_R2I_CERTPOL                            130
+#define X509V3_F_R2I_PCI                                142
 #define X509V3_F_S2I_ASN1_IA5STRING                     100
 #define X509V3_F_S2I_ASN1_INTEGER                       108
 #define X509V3_F_S2I_ASN1_OCTET_STRING                  112
@@ -619,6 +638,7 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED        103
 #define X509V3_R_EXTENSION_VALUE_ERROR                  116
 #define X509V3_R_ILLEGAL_HEX_DIGIT                      113
+#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG            153
 #define X509V3_R_INVALID_BOOLEAN_STRING                         104
 #define X509V3_R_INVALID_EXTENSION_STRING               105
 #define X509V3_R_INVALID_NAME                           106
@@ -630,6 +650,8 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_R_INVALID_OBJECT_IDENTIFIER              110
 #define X509V3_R_INVALID_OPTION                                 138
 #define X509V3_R_INVALID_POLICY_IDENTIFIER              134
+#define X509V3_R_INVALID_PROXY_POLICY_IDENTIFIER        147
+#define X509V3_R_INVALID_PROXY_POLICY_SETTING           151
 #define X509V3_R_INVALID_PURPOSE                        146
 #define X509V3_R_INVALID_SECTION                        135
 #define X509V3_R_INVALID_SYNTAX                                 143
@@ -640,9 +662,16 @@ void ERR_load_X509V3_strings(void);
 #define X509V3_R_NO_ISSUER_CERTIFICATE                  121
 #define X509V3_R_NO_ISSUER_DETAILS                      127
 #define X509V3_R_NO_POLICY_IDENTIFIER                   139
+#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED  148
 #define X509V3_R_NO_PUBLIC_KEY                          114
 #define X509V3_R_NO_SUBJECT_DETAILS                     125
 #define X509V3_R_ODD_NUMBER_OF_DIGITS                   112
+#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED       149
+#define X509V3_R_POLICY_PATH_LENGTH                     152
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED    150
+#define X509V3_R_POLICY_SYNTAX_NOT                      154
+#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED  155
+#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 156
 #define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS           122
 #define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID             123
 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT            111
index edbe2f3a57def88ec396efd4961a0533badbaccb..f6675b574b6f5e0217aea0f5a0e19380444bf939 100644 (file)
@@ -88,6 +88,10 @@ PKCS#12: Personal Information Exchange Syntax Standard, version 1.0.
      (Format: TXT=143173 bytes) (Obsoletes RFC2437) (Status:           
      INFORMATIONAL)                                         
 
+3820 Internet X.509 Public Key Infrastructure (PKI) Proxy Certificate
+     Profile. S. Tuecke, V. Welch, D. Engert, L. Pearlman, M. Thompson.
+     June 2004. (Format: TXT=86374 bytes) (Status: PROPOSED STANDARD)
+
 
 Related:
 --------
index 7e58582f96760959bffed6b8ff6fe7b187ee5e62..02878981f16db780089a2e02929c08736eaa0855 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <ctype.h>
 
 #define USE_SOCKETS
 #include "e_os.h"
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/ssl.h>
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
@@ -169,8 +171,15 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
 static void free_tmp_rsa(void);
 #endif
 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
-#define APP_CALLBACK "Test Callback Argument"
-static char *app_verify_arg = APP_CALLBACK;
+#define APP_CALLBACK_STRING "Test Callback Argument"
+struct app_verify_arg
+       {
+       char *string;
+       int app_verify;
+       int allow_proxy_certs;
+       char *proxy_auth;
+       char *proxy_cond;
+       };
 
 #ifndef OPENSSL_NO_DH
 static DH *get_dh512(void);
@@ -204,6 +213,9 @@ static void sv_usage(void)
 #endif
        fprintf(stderr," -server_auth  - check server certificate\n");
        fprintf(stderr," -client_auth  - do client authentication\n");
+       fprintf(stderr," -proxy        - allow proxy certificates\n");
+       fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
+       fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
        fprintf(stderr," -v            - more output\n");
        fprintf(stderr," -d            - debug output\n");
        fprintf(stderr," -reuse        - use session-id reuse\n");
@@ -353,7 +365,8 @@ int main(int argc, char *argv[])
        int tls1=0,ssl2=0,ssl3=0,ret=1;
        int client_auth=0;
        int server_auth=0,i;
-       int app_verify=0;
+       struct app_verify_arg app_verify_arg =
+               { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
        char *server_cert=TEST_SERVER_CERT;
        char *server_key=NULL;
        char *client_cert=TEST_CLIENT_CERT;
@@ -421,6 +434,16 @@ int main(int argc, char *argv[])
                        server_auth=1;
                else if (strcmp(*argv,"-client_auth") == 0)
                        client_auth=1;
+               else if (strcmp(*argv,"-proxy_auth") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       app_verify_arg.proxy_auth= *(++argv);
+                       }
+               else if (strcmp(*argv,"-proxy_cond") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       app_verify_arg.proxy_cond= *(++argv);
+                       }
                else if (strcmp(*argv,"-v") == 0)
                        verbose=1;
                else if (strcmp(*argv,"-d") == 0)
@@ -533,7 +556,11 @@ int main(int argc, char *argv[])
                        }
                else if (strcmp(*argv,"-app_verify") == 0)
                        {
-                       app_verify = 1;
+                       app_verify_arg.app_verify = 1;
+                       }
+               else if (strcmp(*argv,"-proxy") == 0)
+                       {
+                       app_verify_arg.allow_proxy_certs = 1;
                        }
                else
                        {
@@ -708,20 +735,14 @@ bad:
                SSL_CTX_set_verify(s_ctx,
                        SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                        verify_callback);
-               if (app_verify) 
-                       {
-                       SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
-                       }
+               SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
                }
        if (server_auth)
                {
                BIO_printf(bio_err,"server authentication\n");
                SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
                        verify_callback);
-               if (app_verify) 
-                       {
-                       SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
-                       }
+               SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
                }
        
        {
@@ -1503,6 +1524,22 @@ err:
        return(ret);
        }
 
+static int get_proxy_auth_ex_data_idx(void)
+       {
+       static volatile int idx = -1;
+       if (idx < 0)
+               {
+               CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+               if (idx < 0)
+                       {
+                       idx = X509_STORE_CTX_get_ex_new_index(0,
+                               "SSLtest for verify callback", NULL,NULL,NULL);
+                       }
+               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+               }
+       return idx;
+       }
+
 static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        {
        char *s,buf[256];
@@ -1512,42 +1549,467 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        if (s != NULL)
                {
                if (ok)
-                       fprintf(stderr,"depth=%d %s\n",ctx->error_depth,buf);
+                       fprintf(stderr,"depth=%d %s\n",
+                               ctx->error_depth,buf);
                else
+                       {
                        fprintf(stderr,"depth=%d error=%d %s\n",
                                ctx->error_depth,ctx->error,buf);
+                       }
                }
 
        if (ok == 0)
                {
+               fprintf(stderr,"Error string: %s\n",
+                       X509_verify_cert_error_string(ctx->error));
                switch (ctx->error)
                        {
                case X509_V_ERR_CERT_NOT_YET_VALID:
                case X509_V_ERR_CERT_HAS_EXPIRED:
                case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+                       fprintf(stderr,"  ... ignored.\n");
                        ok=1;
                        }
                }
 
+       if (ok == 1)
+               {
+               X509 *xs = ctx->current_cert;
+#if 0
+               X509 *xi = ctx->current_issuer;
+#endif
+
+               if (xs->ex_flags & EXFLAG_PROXY)
+                       {
+                       unsigned int *letters =
+                               X509_STORE_CTX_get_ex_data(ctx,
+                                       get_proxy_auth_ex_data_idx());
+
+                       if (letters)
+                               {
+                               int found_any = 0;
+                               int i;
+                               PROXY_CERT_INFO_EXTENSION *pci =
+                                       X509_get_ext_d2i(xs, NID_proxyCertInfo,
+                                               NULL, NULL);
+
+                               switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
+                                       {
+                               case NID_Independent:
+                                       /* Completely meaningless in this
+                                          program, as there's no way to
+                                          grant explicit rights to a
+                                          specific PrC.  Basically, using
+                                          id-ppl-Independent is the perfect
+                                          way to grant no rights at all. */
+                                       fprintf(stderr, "  Independent proxy certificate");
+                                       for (i = 0; i < 26; i++)
+                                               letters[i] = 0;
+                                       break;
+                               case NID_id_ppl_inheritAll:
+                                       /* This is basically a NOP, we
+                                          simply let the current rights
+                                          stand as they are. */
+                                       fprintf(stderr, "  Proxy certificate inherits all");
+                                       break;
+                               default:
+                                       s = (char *)
+                                               pci->proxyPolicy->policy->data;
+                                       i = pci->proxyPolicy->policy->length;
+
+                                       /* The algorithm works as follows:
+                                          it is assumed that previous
+                                          iterations or the initial granted
+                                          rights has already set some elements
+                                          of `letters'.  What we need to do is
+                                          to clear those that weren't granted
+                                          by the current PrC as well.  The
+                                          easiest way to do this is to add 1
+                                          to all the elements whose letters
+                                          are given with the current policy.
+                                          That way, all elements that are set
+                                          by the current policy and were
+                                          already set by earlier policies and
+                                          through the original grant of rights
+                                          will get the value 2 or higher.
+                                          The last thing to do is to sweep
+                                          through `letters' and keep the
+                                          elements having the value 2 as set,
+                                          and clear all the others. */
+
+                                       fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
+                                       while(i-- > 0)
+                                               {
+                                               char c = *s++;
+                                               if (isascii(c) && isalpha(c))
+                                                       {
+                                                       if (islower(c))
+                                                               c = toupper(c);
+                                                       letters[c - 'A']++;
+                                                       }
+                                               }
+                                       for (i = 0; i < 26; i++)
+                                               if (letters[i] < 2)
+                                                       letters[i] = 0;
+                                               else
+                                                       letters[i] = 1;
+                                       }
+
+                               found_any = 0;
+                               fprintf(stderr,
+                                       ", resulting proxy rights = ");
+                               for(i = 0; i < 26; i++)
+                                       if (letters[i])
+                                               {
+                                               fprintf(stderr, "%c", i + 'A');
+                                               found_any = 1;
+                                               }
+                               if (!found_any)
+                                       fprintf(stderr, "none");
+                               fprintf(stderr, "\n");
+
+                               PROXY_CERT_INFO_EXTENSION_free(pci);
+                               }
+                       }
+               }
+
        return(ok);
        }
 
+static void process_proxy_debug(int indent, const char *format, ...)
+       {
+       static const char indentation[] =
+               ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+               ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
+       char my_format[256];
+       va_list args;
+
+       BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
+               indent, indent, indentation, format);
+
+       va_start(args, format);
+       vfprintf(stderr, my_format, args);
+       va_end(args);
+       }
+/* Priority levels:
+   0   [!]var, ()
+   1   & ^
+   2   |
+*/
+static int process_proxy_cond_adders(unsigned int letters[26],
+       const char *cond, const char **cond_end, int *pos, int indent);
+static int process_proxy_cond_val(unsigned int letters[26],
+       const char *cond, const char **cond_end, int *pos, int indent)
+       {
+       char c;
+       int ok = 1;
+       int negate = 0;
+
+       while(isspace(*cond))
+               {
+               cond++; (*pos)++;
+               }
+       c = *cond;
+
+       if (debug)
+               process_proxy_debug(indent,
+                       "Start process_proxy_cond_val at position %d: %s\n",
+                       *pos, cond);
+
+       while(c == '!')
+               {
+               negate = !negate;
+               cond++; (*pos)++;
+               while(isspace(*cond))
+                       {
+                       cond++; (*pos)++;
+                       }
+               c = *cond;
+               }
+
+       if (c == '(')
+               {
+               cond++; (*pos)++;
+               ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
+                       indent + 1);
+               cond = *cond_end;
+               if (ok < 0)
+                       goto end;
+               while(isspace(*cond))
+                       {
+                       cond++; (*pos)++;
+                       }
+               c = *cond;
+               if (c != ')')
+                       {
+                       fprintf(stderr,
+                               "Weird condition character in position %d: "
+                               "%c\n", *pos, c);
+                       ok = -1;
+                       goto end;
+                       }
+               cond++; (*pos)++;
+               }
+       else if (isascii(c) && isalpha(c))
+               {
+               if (islower(c))
+                       c = toupper(c);
+               ok = letters[c - 'A'];
+               cond++; (*pos)++;
+               }
+       else
+               {
+               fprintf(stderr,
+                       "Weird condition character in position %d: "
+                       "%c\n", *pos, c);
+               ok = -1;
+               goto end;
+               }
+ end:
+       *cond_end = cond;
+       if (ok >= 0 && negate)
+               ok = !ok;
+
+       if (debug)
+               process_proxy_debug(indent,
+                       "End process_proxy_cond_val at position %d: %s, returning %d\n",
+                       *pos, cond, ok);
+
+       return ok;
+       }
+static int process_proxy_cond_multipliers(unsigned int letters[26],
+       const char *cond, const char **cond_end, int *pos, int indent)
+       {
+       int ok;
+       char c;
+
+       if (debug)
+               process_proxy_debug(indent,
+                       "Start process_proxy_cond_multipliers at position %d: %s\n",
+                       *pos, cond);
+
+       ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
+       cond = *cond_end;
+       if (ok < 0)
+               goto end;
+
+       while(ok >= 0)
+               {
+               while(isspace(*cond))
+                       {
+                       cond++; (*pos)++;
+                       }
+               c = *cond;
+
+               switch(c)
+                       {
+               case '&':
+               case '^':
+                       {
+                       int save_ok = ok;
+
+                       cond++; (*pos)++;
+                       ok = process_proxy_cond_val(letters,
+                               cond, cond_end, pos, indent + 1);
+                       cond = *cond_end;
+                       if (ok < 0)
+                               break;
+
+                       switch(c)
+                               {
+                       case '&':
+                               ok &= save_ok;
+                               break;
+                       case '^':
+                               ok ^= save_ok;
+                               break;
+                       default:
+                               fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+                                       " STOPPING\n");
+                               EXIT(1);
+                               }
+                       }
+                       break;
+               default:
+                       goto end;
+                       }
+               }
+ end:
+       if (debug)
+               process_proxy_debug(indent,
+                       "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
+                       *pos, cond, ok);
+
+       *cond_end = cond;
+       return ok;
+       }
+static int process_proxy_cond_adders(unsigned int letters[26],
+       const char *cond, const char **cond_end, int *pos, int indent)
+       {
+       int ok;
+       char c;
+
+       if (debug)
+               process_proxy_debug(indent,
+                       "Start process_proxy_cond_adders at position %d: %s\n",
+                       *pos, cond);
+
+       ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
+               indent + 1);
+       cond = *cond_end;
+       if (ok < 0)
+               goto end;
+
+       while(ok >= 0)
+               {
+               while(isspace(*cond))
+                       {
+                       cond++; (*pos)++;
+                       }
+               c = *cond;
+
+               switch(c)
+                       {
+               case '|':
+                       {
+                       int save_ok = ok;
+
+                       cond++; (*pos)++;
+                       ok = process_proxy_cond_multipliers(letters,
+                               cond, cond_end, pos, indent + 1);
+                       cond = *cond_end;
+                       if (ok < 0)
+                               break;
+
+                       switch(c)
+                               {
+                       case '|':
+                               ok |= save_ok;
+                               break;
+                       default:
+                               fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+                                       " STOPPING\n");
+                               EXIT(1);
+                               }
+                       }
+                       break;
+               default:
+                       goto end;
+                       }
+               }
+ end:
+       if (debug)
+               process_proxy_debug(indent,
+                       "End process_proxy_cond_adders at position %d: %s, returning %d\n",
+                       *pos, cond, ok);
+
+       *cond_end = cond;
+       return ok;
+       }
+
+static int process_proxy_cond(unsigned int letters[26],
+       const char *cond, const char **cond_end)
+       {
+       int pos = 1;
+       return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
+       }
+
 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
        {
-       char *s = NULL,buf[256];
        int ok=1;
+       struct app_verify_arg *cb_arg = arg;
+       unsigned int letters[26]; /* only used with proxy_auth */
 
-       fprintf(stderr, "In app_verify_callback, allowing cert. ");
-       fprintf(stderr, "Arg is: %s\n", (char *)arg);
-       fprintf(stderr, "Finished printing do we have a context? 0x%x a cert? 0x%x\n",
-                       (unsigned int)ctx, (unsigned int)ctx->cert);
-       if (ctx->cert)
-               s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
-       if (s != NULL)
+       if (cb_arg->app_verify)
                {
+               char *s = NULL,buf[256];
+
+               fprintf(stderr, "In app_verify_callback, allowing cert. ");
+               fprintf(stderr, "Arg is: %s\n", cb_arg->string);
+               fprintf(stderr, "Finished printing do we have a context? 0x%x a cert? 0x%x\n",
+                       (unsigned int)ctx, (unsigned int)ctx->cert);
+               if (ctx->cert)
+                       s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+               if (s != NULL)
+                       {
                        fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+                       }
+               return(1);
+               }
+       if (cb_arg->proxy_auth)
+               {
+               int found_any = 0, i;
+               char *sp;
+
+               for(i = 0; i < 26; i++)
+                       letters[i] = 0;
+               for(sp = cb_arg->proxy_auth; *sp; sp++)
+                       {
+                       char c = *sp;
+                       if (isascii(c) && isalpha(c))
+                               {
+                               if (islower(c))
+                                       c = toupper(c);
+                               letters[c - 'A'] = 1;
+                               }
+                       }
+
+               fprintf(stderr,
+                       "  Initial proxy rights = ");
+               for(i = 0; i < 26; i++)
+                       if (letters[i])
+                               {
+                               fprintf(stderr, "%c", i + 'A');
+                               found_any = 1;
+                               }
+               if (!found_any)
+                       fprintf(stderr, "none");
+               fprintf(stderr, "\n");
+
+               X509_STORE_CTX_set_ex_data(ctx,
+                       get_proxy_auth_ex_data_idx(),letters);
                }
+       if (cb_arg->allow_proxy_certs)
+               {
+               X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+               }
+
+#ifndef OPENSSL_NO_X509_VERIFY
+# ifdef OPENSSL_FIPS
+       if(s->version == TLS1_VERSION)
+               FIPS_allow_md5(1);
+# endif
+       ok = X509_verify_cert(ctx);
+# ifdef OPENSSL_FIPS
+       if(s->version == TLS1_VERSION)
+               FIPS_allow_md5(0);
+# endif
+#endif
+
+       if (cb_arg->proxy_auth)
+               {
+               if (ok)
+                       {
+                       const char *cond_end = NULL;
 
+                       ok = process_proxy_cond(letters,
+                               cb_arg->proxy_cond, &cond_end);
+
+                       if (ok < 0)
+                               EXIT(3);
+                       if (*cond_end)
+                               {
+                               fprintf(stderr, "Stopped processing condition before it's end.\n");
+                               ok = 0;
+                               }
+                       if (!ok)
+                               fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
+                                       cb_arg->proxy_cond);
+                       else
+                               fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
+                                       cb_arg->proxy_cond);
+                       }
+               }
        return(ok);
        }
 
index b941b7ae15703a6eba452835c5f28a7eb85d19c6..21da59a73af31eac3a2e5f9e77161cb1ae5a4df1 100644 (file)
@@ -23,3 +23,11 @@ organizationName_value               = Dodgy Brothers
 
 commonName                     = Common Name (eg, YOUR name)
 commonName_value               = Dodgy CA
+
+[ v3_ca ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+basicConstraints = CA:true,pathlen:1
+keyUsage = cRLSign, keyCertSign
+issuerAltName=issuer:copy
+
index 569f78151f9723812b87ae621fa5d7cf3834acac..6aeedf7fa3fdc23c6d2383bbd7397612ca0f4ff1 100644 (file)
@@ -259,20 +259,26 @@ test_gen:
        @echo "Generate and verify a certificate request"
        @sh ./testgen
 
-test_ss keyU.ss certU.ss certCA.ss: testss
+test_ss keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+               intP1.ss intP2.ss: testss
        @echo "Generate and certify a test certificate"
        @sh ./testss
+       @cat certCA.ss certU.ss > intP1.ss
+       @cat certCA.ss certU.ss certP1.ss > intP2.ss
 
 test_engine: 
        @echo "Manipulate the ENGINE structures"
        ../util/shlib_wrap.sh ./$(ENGINETEST)
 
-test_ssl: keyU.ss certU.ss certCA.ss
+test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
+               intP1.ss intP2.ss
        @echo "test SSL protocol"
        @if egrep 'define OPENSSL_FIPS' $(TOP)/include/openssl/opensslconf.h > /dev/null; then \
          sh ./testfipsssl keyU.ss certU.ss certCA.ss; \
        fi
        @sh ./testssl keyU.ss certU.ss certCA.ss
+       @sh ./testsslproxy keyP1.ss certP1.ss intP1.ss
+       @sh ./testsslproxy keyP2.ss certP2.ss intP2.ss
 
 test_ca:
        @if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
@@ -757,25 +763,26 @@ ssltest.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
 ssltest.o: ../include/openssl/bio.h ../include/openssl/blowfish.h
 ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssltest.o: ../include/openssl/cast.h ../include/openssl/comp.h
-ssltest.o: ../include/openssl/crypto.h ../include/openssl/des.h
-ssltest.o: ../include/openssl/des_old.h ../include/openssl/dh.h
-ssltest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h
-ssltest.o: ../include/openssl/evp.h ../include/openssl/fips.h
-ssltest.o: ../include/openssl/idea.h ../include/openssl/kssl.h
-ssltest.o: ../include/openssl/lhash.h ../include/openssl/md2.h
-ssltest.o: ../include/openssl/md4.h ../include/openssl/md5.h
-ssltest.o: ../include/openssl/mdc2.h ../include/openssl/obj_mac.h
-ssltest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-ssltest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ssltest.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssltest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-ssltest.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
-ssltest.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h
-ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssltest.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
-ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssltest.c
+ssltest.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ssltest.o: ../include/openssl/des.h ../include/openssl/des_old.h
+ssltest.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ssltest.o: ../include/openssl/e_os2.h ../include/openssl/engine.h
+ssltest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssltest.o: ../include/openssl/fips.h ../include/openssl/idea.h
+ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssltest.o: ../include/openssl/md2.h ../include/openssl/md4.h
+ssltest.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
+ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssltest.o: ../include/openssl/rand.h ../include/openssl/rc2.h
+ssltest.o: ../include/openssl/rc4.h ../include/openssl/rc5.h
+ssltest.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
+ssltest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssltest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssltest.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssltest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssltest.o: ../include/openssl/tls1.h ../include/openssl/ui.h
+ssltest.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
+ssltest.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssltest.c
index c89692d5199c32e1ff74c59853175e868b00f7b3..0c0ebb5f67294dc455424b807ae0b0ed375c8367 100644 (file)
@@ -26,3 +26,11 @@ organizationName_value          = Dodgy Brothers
 
 1.commonName                   = Common Name (eg, YOUR name)
 1.commonName_value             = Brother 2
+
+[ v3_ee ]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+basicConstraints = CA:false
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+issuerAltName=issuer:copy
+
index f6a629c8e1cda868380582fbab50317f741b6a8f..1a426857d31e16569867a24c11b1006a14db92ec 100644 (file)
@@ -17,6 +17,18 @@ Ukey="keyU.ss"
 Ureq="reqU.ss"
 Ucert="certU.ss"
 
+P1conf="P1ss.cnf"
+P1key="keyP1.ss"
+P1req="reqP1.ss"
+P1cert="certP1.ss"
+P1intermediate="tmp_intP1.ss"
+
+P2conf="P2ss.cnf"
+P2key="keyP2.ss"
+P2req="reqP2.ss"
+P2cert="certP2.ss"
+P2intermediate="tmp_intP2.ss"
+
 echo
 echo "make a certificate request using 'req'"
 
@@ -35,7 +47,7 @@ if [ $? != 0 ]; then
 fi
 echo
 echo "convert the certificate request into a self signed certificate using 'x509'"
-$x509cmd -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey >err.ss
+$x509cmd -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey -extfile $CAconf -extensions v3_ca >err.ss
 if [ $? != 0 ]; then
        echo "error using 'x509' to self sign a certificate request"
        exit 1
@@ -68,18 +80,18 @@ if [ $? != 0 ]; then
 fi
 
 echo
-echo "make another certificate request using 'req'"
+echo "make a user certificate request using 'req'"
 $reqcmd -config $Uconf -out $Ureq -keyout $Ukey $req_new >err.ss
 if [ $? != 0 ]; then
-       echo "error using 'req' to generate a certificate request"
+       echo "error using 'req' to generate a user certificate request"
        exit 1
 fi
 
 echo
-echo "sign certificate request with the just created CA via 'x509'"
-$x509cmd -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey >err.ss
+echo "sign user certificate request with the just created CA via 'x509'"
+$x509cmd -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -extfile $Uconf -extensions v3_ee >err.ss
 if [ $? != 0 ]; then
-       echo "error using 'x509' to sign a certificate request"
+       echo "error using 'x509' to sign a user certificate request"
        exit 1
 fi
 
@@ -88,6 +100,50 @@ echo
 echo "Certificate details"
 $x509cmd -subject -issuer -startdate -enddate -noout -in $Ucert
 
+echo
+echo "make a proxy certificate request using 'req'"
+$reqcmd -config $P1conf -out $P1req -keyout $P1key $req_new >err.ss
+if [ $? != 0 ]; then
+       echo "error using 'req' to generate a proxy certificate request"
+       exit 1
+fi
+
+echo
+echo "sign proxy certificate request with the just created user certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P1req -days 30 -req -out $P1cert -CA $Ucert -CAkey $Ukey -extfile $P1conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+       echo "error using 'x509' to sign a proxy certificate request"
+       exit 1
+fi
+
+cat $Ucert > $P1intermediate
+$verifycmd -CAfile $CAcert -untrusted $P1intermediate $P1cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P1cert
+
+echo
+echo "make another proxy certificate request using 'req'"
+$reqcmd -config $P2conf -out $P2req -keyout $P2key $req_new >err.ss
+if [ $? != 0 ]; then
+       echo "error using 'req' to generate another proxy certificate request"
+       exit 1
+fi
+
+echo
+echo "sign second proxy certificate request with the first proxy certificate via 'x509'"
+$x509cmd -CAcreateserial -in $P2req -days 30 -req -out $P2cert -CA $P1cert -CAkey $P1key -extfile $P2conf -extensions v3_proxy >err.ss
+if [ $? != 0 ]; then
+       echo "error using 'x509' to sign a second proxy certificate request"
+       exit 1
+fi
+
+cat $Ucert $P1cert > $P2intermediate
+$verifycmd -CAfile $CAcert -untrusted $P2intermediate $P2cert
+echo
+echo "Certificate details"
+$x509cmd -subject -issuer -startdate -enddate -noout -in $P2cert
+
 echo
 echo The generated CA certificate is $CAcert
 echo The generated CA private key is $CAkey
@@ -95,5 +151,13 @@ echo The generated CA private key is $CAkey
 echo The generated user certificate is $Ucert
 echo The generated user private key is $Ukey
 
+echo The first generated proxy certificate is $P1cert
+echo The first generated proxy private key is $P1key
+
+echo The second generated proxy certificate is $P2cert
+echo The second generated proxy private key is $P2key
+
 /bin/rm err.ss
+#/bin/rm $P1intermediate
+#/bin/rm $P2intermediate
 exit 0
index 562b338cf61725d3fa36ddb10574878f240842b0..56fb7446e0448fce0867cf6f7a9a1238618b5f91 100755 (executable)
@@ -2855,3 +2855,15 @@ private_RC2_set_key                     3296     EXIST:OPENSSL_FIPS:FUNCTION:RC2
 private_MD4_Init                        3297   EXIST:OPENSSL_FIPS:FUNCTION:MD4
 private_BF_set_key                      3298   EXIST:OPENSSL_FIPS:FUNCTION:BF
 private_MD2_Init                        3299   EXIST:OPENSSL_FIPS:FUNCTION:MD2
+d2i_PROXY_CERT_INFO_EXTENSION           3300   EXIST::FUNCTION:
+PROXY_POLICY_it                         3301   EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PROXY_POLICY_it                         3301   EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+i2d_PROXY_POLICY                        3302   EXIST::FUNCTION:
+i2d_PROXY_CERT_INFO_EXTENSION           3303   EXIST::FUNCTION:
+d2i_PROXY_POLICY                        3304   EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_new           3305   EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_free          3306   EXIST::FUNCTION:
+PROXY_CERT_INFO_EXTENSION_it            3307   EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
+PROXY_CERT_INFO_EXTENSION_it            3307   EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
+PROXY_POLICY_free                       3308   EXIST::FUNCTION:
+PROXY_POLICY_new                        3309   EXIST::FUNCTION:
index 20146efb43715f7f74eb3cf1e27af3814edd20d1..60e534807eb381b554866fb70a854a7c61426e30 100644 (file)
@@ -263,7 +263,7 @@ foreach $lib (keys %csrc)
        } else {
            push @out,
 "/* ====================================================================\n",
-" * Copyright (c) 2001-2004 The OpenSSL Project.  All rights reserved.\n",
+" * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.\n",
 " *\n",
 " * Redistribution and use in source and binary forms, with or without\n",
 " * modification, are permitted provided that the following conditions\n",