Browse Source

Merge pull request #5167 from ejohnstown/cac-ext

Add support for some FPKI certificate cases, UUID, FASC-N, PIV extension
David Garske 1 year ago
parent
commit
b84b808b1b
10 changed files with 898 additions and 142 deletions
  1. BIN
      certs/fpki-cert.der
  2. 2 1
      certs/include.am
  3. 15 0
      certs/renewcerts.sh
  4. 37 0
      certs/renewcerts/wolfssl.cnf
  5. 3 0
      configure.ac
  6. 1 1
      src/x509.c
  7. 42 2
      tests/api.c
  8. 713 132
      wolfcrypt/src/asn.c
  9. 79 6
      wolfssl/wolfcrypt/asn.h
  10. 6 0
      wolfssl/wolfcrypt/asn_public.h

BIN
certs/fpki-cert.der


+ 2 - 1
certs/include.am

@@ -63,7 +63,8 @@ EXTRA_DIST += \
 	     certs/csr.ext.der \
 	     certs/entity-no-ca-bool-cert.pem \
 	     certs/entity-no-ca-bool-key.pem \
-	     certs/x942dh2048.pem
+	     certs/x942dh2048.pem \
+	     certs/fpki-cert.der
 
 EXTRA_DIST += \
 	     certs/ca-key.der \

+ 15 - 0
certs/renewcerts.sh

@@ -27,6 +27,7 @@
 #                       client-relative-uri.pem
 #                       client-crl-dist.pem
 #                       entity-no-ca-bool-cert.pem
+#                       fpki-cert.der
 # updates the following crls:
 #                       crl/cliCrl.pem
 #                       crl/crl.pem
@@ -344,6 +345,20 @@ run_renewcerts(){
     echo "End of section"
     echo "---------------------------------------------------------------------"
     ###########################################################
+    ########## update and sign fpki-cert.der ################
+    ###########################################################
+    echo "Updating fpki-cert.der"
+    echo ""
+    #pipe the following arguments to openssl req...
+    echo -e "US\\nMontana\\nBozeman\\nwolfSSL\\nFPKI\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | openssl req -new -key server-key.pem -config ./wolfssl.cnf -nodes > fpki-req.pem
+    check_result $? "Step 1"
+
+    openssl x509 -req -in fpki-req.pem -extfile wolfssl.cnf -extensions fpki_ext -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out fpki-cert.der -outform DER
+    check_result $? "Step 2"
+    rm fpki-req.pem
+    echo "End of section"
+    echo "---------------------------------------------------------------------"
+    ###########################################################
     ########## update and sign server-cert.pem ################
     ###########################################################
     echo "Updating server-cert.pem"

+ 37 - 0
certs/renewcerts/wolfssl.cnf

@@ -335,3 +335,40 @@ clock_precision_digits  = 0                                     # (optional)
 ordering                = yes                                   # timestamps?
 tsa_name                = yes                                   # include?
 ess_cert_id_chain       = no                                    # include chain?
+
+
+[fpki_ext]
+basicConstraints = CA:FALSE,pathlen:0
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+keyUsage = critical, digitalSignature
+extendedKeyUsage = critical, clientAuth, 1.3.6.1.4.1.311.20.2.2, 1.3.6.1.5.2.3.4, 1.3.6.1.5.5.7.3.21
+subjectAltName = @FASC_UUID_altname
+certificatePolicies = 2.16.840.1.101.3.2.1.3.13, 2.16.840.1.101.3.2.1.3.40, 2.16.840.1.101.3.2.1.3.41, 2.16.840.1.101.3.2.1.3.45
+subjectDirectoryAttributes = ASN1:SEQUENCE:SubjDirAttr
+policyConstraints = requireExplicitPolicy:0
+2.16.840.1.101.3.6.10.1 = ASN1:SEQUENCE:PIVCertExt
+
+# using example UUID from RFC4122
+[FASC_UUID_altname]
+otherName.1 = 1.3.6.1.4.1.311.20.2.3;UTF8:facts@wolfssl.com
+otherName.2 = 2.16.840.1.101.3.6.6;FORMAT:HEX,OCT:D1:38:10:D8:28:AF:2C:10:84:35:15:A1:68:58:28:AF:02:10:86:A2:84:E7:39:C3:EB
+URI = urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+
+[SubjDirAttr]
+attribute = SEQUENCE:SDA_attr
+
+[SDA_attr]
+type = OID:1.3.6.1.5.5.7.9.4
+values = SET:SDA_coc
+
+[SDA_coc]
+value = PRINTABLESTRING:US
+
+[PIVCertExt]
+attribute = SEQUENCE:PCE_attr
+
+[PCE_attr]
+type = OID:2.16.840.1.101.3.6.9.1
+value = BOOLEAN:true
+

+ 3 - 0
configure.ac

@@ -756,6 +756,9 @@ then
 
     # Store issuer name components when parsing certificates.
     AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_ISSUER_NAMES"
+
+    # Certificate extensions and alt. names for FPKI use
+    AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SUBJ_DIR_ATTR -DWOLFSSL_FPKI -DWOLFSSL_SUBJ_INFO_ACC"
 fi
 
 

+ 1 - 1
src/x509.c

@@ -2201,7 +2201,7 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
             WOLFSSL_MSG("Private Key Usage Period extension not supported");
             break;
 
-        case SUBJECT_INFO_ACCESS:
+        case SUBJ_INFO_ACC_OID:
             WOLFSSL_MSG("Subject Info Access extension not supported");
             break;
 

+ 42 - 2
tests/api.c

@@ -2261,6 +2261,44 @@ static void test_wolfSSL_CertManagerNameConstraint5(void)
 #endif
 }
 
+static void test_wolfSSL_FPKI(void)
+{
+#if defined(WOLFSSL_FPKI) && !defined(NO_FILESYSTEM)
+    XFILE f;
+    const char* fpkiCert = "./certs/fpki-cert.der";
+    DecodedCert cert;
+    byte buf[4096];
+    byte* uuid;
+    byte* fascn;
+    word32 fascnSz;
+    word32 uuidSz;
+    int bytes;
+
+    printf(testingFmt, "test_wolfSSL_FPKI");
+    f = XFOPEN(fpkiCert, "rb");
+    AssertTrue((f != XBADFILE));
+    bytes = (int)XFREAD(buf, 1, sizeof(buf), f);
+    XFCLOSE(f);
+
+    wc_InitDecodedCert(&cert, buf, bytes, NULL);
+    AssertIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
+    AssertIntEQ(wc_GetFASCNFromCert(&cert, NULL, &fascnSz), LENGTH_ONLY_E) ;
+    fascn = (byte*)XMALLOC(fascnSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    AssertNotNull(fascn);
+    AssertIntEQ(wc_GetFASCNFromCert(&cert, fascn, &fascnSz), 0);
+    XFREE(fascn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    AssertIntEQ(wc_GetUUIDFromCert(&cert, NULL, &uuidSz), LENGTH_ONLY_E);
+    uuid = (byte*)XMALLOC(uuidSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    AssertNotNull(uuid);
+    AssertIntEQ(wc_GetUUIDFromCert(&cert, uuid, &uuidSz), 0);
+    XFREE(uuid, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    wc_FreeDecodedCert(&cert);
+
+    printf(resultFmt, passed);
+#endif
+}
+
 static void test_wolfSSL_CertManagerCRL(void)
 {
 #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
@@ -8979,14 +9017,15 @@ static void test_wolfSSL_URI(void)
 
     x509 = wolfSSL_X509_load_certificate_file(uri, WOLFSSL_FILETYPE_PEM);
     AssertNotNull(x509);
-
     wolfSSL_FreeX509(x509);
 
     x509 = wolfSSL_X509_load_certificate_file(badUri, WOLFSSL_FILETYPE_PEM);
-#if !defined(IGNORE_NAME_CONSTRAINTS) && !defined(WOLFSSL_NO_ASN_STRICT)
+#if !defined(IGNORE_NAME_CONSTRAINTS) && !defined(WOLFSSL_NO_ASN_STRICT) \
+    && !defined(WOLFSSL_FPKI)
     AssertNull(x509);
 #else
     AssertNotNull(x509);
+    wolfSSL_FreeX509(x509);
 #endif
 
     printf(resultFmt, passed);
@@ -55524,6 +55563,7 @@ void ApiTest(void)
     test_wolfSSL_CertManagerNameConstraint3();
     test_wolfSSL_CertManagerNameConstraint4();
     test_wolfSSL_CertManagerNameConstraint5();
+    test_wolfSSL_FPKI();
     test_wolfSSL_CertManagerCRL();
     test_wolfSSL_CTX_load_verify_locations_ex();
     test_wolfSSL_CTX_load_verify_buffer_ex();

File diff suppressed because it is too large
+ 713 - 132
wolfcrypt/src/asn.c


+ 79 - 6
wolfssl/wolfcrypt/asn.h

@@ -975,6 +975,8 @@ enum Misc_ASN {
 
     PEM_LINE_SZ        = 64,               /* Length of Base64 encoded line, not including new line */
     PEM_LINE_LEN       = PEM_LINE_SZ + 12, /* PEM line max + fudge */
+
+    COUNTRY_CODE_LEN   = 2,        /* RFC 3739 */
 };
 
 #ifndef WC_MAX_NAME_ENTRIES
@@ -1010,6 +1012,9 @@ enum Oid_Types {
     oidTlsExtType       = 18,
     oidCrlExtType       = 19,
     oidCsrAttrType      = 20,
+#ifdef WOLFSSL_SUBJ_DIR_ATTR
+    oidSubjDirAttrType  = 21,
+#endif
     oidIgnoreType
 };
 
@@ -1129,7 +1134,7 @@ enum Extensions_Sum {
     EXT_KEY_USAGE_OID         = 151, /* 2.5.29.37 */
     NAME_CONS_OID             = 144, /* 2.5.29.30 */
     PRIV_KEY_USAGE_PERIOD_OID = 130, /* 2.5.29.16 */
-    SUBJECT_INFO_ACCESS       = 79,  /* 1.3.6.1.5.5.7.1.11 */
+    SUBJ_INFO_ACC_OID         = 79,  /* 1.3.6.1.5.5.7.1.11 */
     POLICY_MAP_OID            = 147, /* 2.5.29.33 */
     POLICY_CONST_OID          = 150, /* 2.5.29.36 */
     ISSUE_ALT_NAMES_OID       = 132, /* 2.5.29.18 */
@@ -1137,13 +1142,22 @@ enum Extensions_Sum {
     NETSCAPE_CT_OID           = 753, /* 2.16.840.1.113730.1.1 */
     OCSP_NOCHECK_OID          = 121, /* 1.3.6.1.5.5.7.48.1.5
                                          id-pkix-ocsp-nocheck */
+    SUBJ_DIR_ATTR_OID         = 123, /* 2.5.29.9 */
 
-    AKEY_PACKAGE_OID          = 1048 /* 2.16.840.1.101.2.1.2.78.5
+    AKEY_PACKAGE_OID          = 1048, /* 2.16.840.1.101.2.1.2.78.5
                                         RFC 5958  - Asymmetric Key Packages */
+    FASCN_OID = 419, /* 2.16.840.1.101.3.6.6 Federal PKI Policy FASC-N */
+    UPN_OID   = 265  /* 1.3.6.1.4.1.311.20.2.3 UPN */
 };
 
 enum CertificatePolicy_Sum {
-    CP_ANY_OID      = 146  /* id-ce 32 0 */
+    CP_ANY_OID              = 146, /* id-ce 32 0 */
+#ifdef WOLFSSL_FPKI
+    CP_FPKI_COMMON_AUTH_OID = 426, /* 2.16.840.1.101.3.2.1.3.13 */
+    CP_FPKI_PIV_AUTH_OID    = 453, /* 2.16.840.1.101.3.2.1.3.40 */
+    CP_FPKI_PIV_AUTH_HW_OID = 454, /* 2.16.840.1.101.3.2.1.3.41 */
+    CP_FPKI_PIVI_AUTH_OID   = 458  /* 2.16.840.1.101.3.2.1.3.45 */
+#endif /* WOLFSSL_FPKI */
 };
 
 enum SepHardwareName_Sum {
@@ -1151,10 +1165,15 @@ enum SepHardwareName_Sum {
 };
 
 enum AuthInfo_Sum {
-    AIA_OCSP_OID      = 116, /* 1.3.6.1.5.5.7.48.1 */
-    AIA_CA_ISSUER_OID = 117  /* 1.3.6.1.5.5.7.48.2 */
+    AIA_OCSP_OID      = 116, /* 1.3.6.1.5.5.7.48.1, id-ad-ocsp */
+    AIA_CA_ISSUER_OID = 117, /* 1.3.6.1.5.5.7.48.2, id-ad-caIssuers */
+    #ifdef WOLFSSL_SUBJ_INFO_ACC
+    AIA_CA_REPO_OID   = 120  /* 1.3.6.1.5.5.7.48.5, id-ad-caRepository */
+    #endif /* WOLFSSL_SUBJ_INFO_ACC */
 };
 
+#define ID_PKIX(num) (67+(num)) /* 1.3.6.1.5.5.7.num, id-pkix num */
+#define ID_KP(num) (ID_PKIX(3)+(num)) /* 1.3.6.1.5.5.7.3.num, id-kp num */
 enum ExtKeyUsage_Sum { /* From RFC 5280 */
     EKU_ANY_OID         = 151, /* 2.5.29.37.0, anyExtendedKeyUsage         */
     EKU_SERVER_AUTH_OID = 71,  /* 1.3.6.1.5.5.7.3.1, id-kp-serverAuth      */
@@ -1162,9 +1181,27 @@ enum ExtKeyUsage_Sum { /* From RFC 5280 */
     EKU_CODESIGNING_OID = 73,  /* 1.3.6.1.5.5.7.3.3, id-kp-codeSigning     */
     EKU_EMAILPROTECT_OID = 74, /* 1.3.6.1.5.5.7.3.4, id-kp-emailProtection */
     EKU_TIMESTAMP_OID   = 78,  /* 1.3.6.1.5.5.7.3.8, id-kp-timeStamping    */
-    EKU_OCSP_SIGN_OID   = 79   /* 1.3.6.1.5.5.7.3.9, id-kp-OCSPSigning     */
+    EKU_OCSP_SIGN_OID   = 79,  /* 1.3.6.1.5.5.7.3.9, id-kp-OCSPSigning     */
+
+    /* From RFC 6187: X.509v3 Certificates for Secure Shell Authenticaiton */
+    EKU_SSH_CLIENT_AUTH_OID    = ID_KP(21), /* id-kp-secureShellClient */
+    EKU_SSH_MSCL_OID           = 264,
+        /* 1.3.6.1.4.1.311.20.2.2, MS Smart Card Logon */
+    EKU_SSH_KP_CLIENT_AUTH_OID = 64
+        /* 1.3.6.1.5.2.3.4, id-pkinit-KPClientAuth*/
 };
 
+#ifdef WOLFSSL_SUBJ_DIR_ATTR
+#define ID_PDA(num) (ID_PKIX(9)+(num)) /* 1.3.6.1.5.5.7.9.num, id-pda num */
+enum SubjDirAttr_Sum { /* From RFC 3739, section 3.3.2 */
+    SDA_DOB_OID    = ID_PDA(1), /* id-pda-dateOfBirth */
+    SDA_POB_OID    = ID_PDA(2), /* id-pda-placeOfBirth */
+    SDA_GENDER_OID = ID_PDA(3), /* id-pda-gender */
+    SDA_COC_OID    = ID_PDA(4), /* id-pda-countryOfCitizenship */
+    SDA_COR_OID    = ID_PDA(5)  /* id-pda-countryOfResidence */
+};
+#endif /* WOLFSSL_SUBJ_DIR_ATTR */
+
 #ifdef HAVE_LIBZ
 enum CompressAlg_Sum {
     ZLIBc = 679  /* 1.2.840.113549.1.9.16.3.8, id-alg-zlibCompress */
@@ -1223,6 +1260,11 @@ enum CsrAttrType {
 #define EXTKEYUSE_CLIENT_AUTH 0x04
 #define EXTKEYUSE_SERVER_AUTH 0x02
 #define EXTKEYUSE_ANY         0x01
+#ifdef WOLFSSL_WOLFSSH
+    #define EXTKEYUSE_SSH_CLIENT_AUTH    0x01
+    #define EXTKEYUSE_SSH_MSCL           0x02
+    #define EXTKEYUSE_SSH_KP_CLIENT_AUTH 0x04
+#endif /* WOLFSSL_WOLFSSH */
 
 #define WC_NS_SSL_CLIENT      0x80
 #define WC_NS_SSL_SERVER      0x40
@@ -1252,8 +1294,15 @@ struct DNS_entry {
 #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
     char*      ipString; /* human readable form of IP address */
 #endif
+#ifdef WOLFSSL_FPKI
+    int        oidSum; /* provide oid sum for verification */
+#endif
 };
 
+#ifdef WOLFSSL_FPKI
+    /* RFC4122 i.e urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 */
+    #define DEFAULT_UUID_SZ 45
+#endif
 
 typedef struct Base_entry  Base_entry;
 
@@ -1535,6 +1584,9 @@ struct DecodedCert {
     byte    policyConstSkip;         /* Policy Constraints skip certs value */
     word16  extKeyUsage;             /* Key usage bitfield               */
     byte    extExtKeyUsage;          /* Extended Key usage bitfield      */
+#ifdef WOLFSSL_WOLFSSH
+    byte    extExtKeyUsageSsh;       /* Extended Key Usage bitfield for SSH */
+#endif /* WOLFSSL_WOLFSSH */
 
 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     const byte* extExtKeyUsageSrc;
@@ -1553,6 +1605,21 @@ struct DecodedCert {
     const byte* extSubjAltNameSrc;
     word32  extSubjAltNameSz;
 #endif
+#ifdef WOLFSSL_SUBJ_DIR_ATTR
+    char countryOfCitizenship[COUNTRY_CODE_LEN+1]; /* ISO 3166 Country Code */
+    #ifdef OPENSSL_ALL
+        const byte* extSubjDirAttrSrc;
+        word32 extSubjDirAttrSz;
+    #endif
+#endif /* WOLFSSL_SUBJ_DIR_ATTR */
+#ifdef WOLFSSL_SUBJ_INFO_ACC
+    const byte* extSubjInfoAccCaRepo;
+    word32 extSubjInfoAccCaRepoSz;
+    #ifdef OPENSSL_ALL
+        const byte* extSubjInfoAccSrc;
+        word32 extSubjInfoAccSz;
+    #endif
+#endif /* WOLFSSL_SUBJ_INFO_ACC */
 
 #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
     word32  pkCurveOID;           /* Public Key's curve OID */
@@ -1732,6 +1799,12 @@ struct DecodedCert {
     byte extSubjKeyIdCrit : 1;
     byte extKeyUsageCrit : 1;
     byte extExtKeyUsageCrit : 1;
+#ifdef WOLFSSL_SUBJ_DIR_ATTR
+    byte extSubjDirAttrSet : 1;
+#endif
+#ifdef WOLFSSL_SUBJ_INFO_ACC
+    byte extSubjInfoAccSet : 1;
+#endif
 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
     byte extCertPolicyCrit : 1;
 #endif

+ 6 - 0
wolfssl/wolfcrypt/asn_public.h

@@ -830,6 +830,12 @@ WOLFSSL_API int  wc_ParseCert(
 WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
                                         byte* derKey, word32* derKeySz);
 
+#ifdef WOLFSSL_FPKI
+WOLFSSL_API int wc_GetUUIDFromCert(struct DecodedCert* cert,
+                                    byte* uuid, word32* uuidSz);
+WOLFSSL_API int wc_GetFASCNFromCert(struct DecodedCert* cert,
+                                    byte* fascn, word32* fascnSz);
+#endif /* WOLFSSL_FPKI */
 #ifdef __cplusplus
     } /* extern "C" */
 #endif

Some files were not shown because too many files changed in this diff