Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) New chain verification flags for Suite B levels of security. Check algorithms are acceptable when flags are set in X509_verify_cert. [Steve Henson] *) Make tls1_check_chain return a set of flags indicating checks passed by a certificate chain. Add additional tests to handle client certificates: checks for matching certificate type and issuer name Loading apps/apps.c +6 −0 Original line number Diff line number Diff line Loading @@ -2376,6 +2376,12 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; else if (!strcmp(arg, "-trusted_first")) flags |= X509_V_FLAG_TRUSTED_FIRST; else if (!strcmp(arg, "-suiteB_128_only")) flags |= X509_V_FLAG_SUITEB_128_LOS_ONLY; else if (!strcmp(arg, "-suiteB_128")) flags |= X509_V_FLAG_SUITEB_128_LOS; else if (!strcmp(arg, "-suiteB_192")) flags |= X509_V_FLAG_SUITEB_192_LOS; else return 0; Loading crypto/x509/x509.h +5 −0 Original line number Diff line number Diff line Loading @@ -966,6 +966,11 @@ int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); int X509_check_suiteb_chain(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags); int X509_check_suiteb_crl(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); unsigned long X509_issuer_and_serial_hash(X509 *a); Loading crypto/x509/x509_cmp.c +124 −0 Original line number Diff line number Diff line Loading @@ -341,3 +341,127 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k) return 1; return 0; } /* Check a suite B algorithm is permitted: pass in a public key and * the NID of its signature (or 0 if no signature). The pflags is * a pointer to a flags field which must contain the suite B verification * flags. */ static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) { const EC_GROUP *grp = NULL; int curve_nid; if (pkey && pkey->type == EVP_PKEY_EC) grp = EC_KEY_get0_group(pkey->pkey.ec); if (!grp) return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; curve_nid = EC_GROUP_get_curve_name(grp); /* Check curve is consistent with LOS */ if (curve_nid == NID_secp384r1) /* P-384 */ { /* Check signature algorithm is consistent with * curve. */ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; /* If we encounter P-384 we cannot use P-256 later */ *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; } else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */ { if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; } else return X509_V_ERR_SUITE_B_INVALID_CURVE; return X509_V_OK; } int X509_check_suiteb_chain(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags) { int rv, i, sign_nid; EVP_PKEY *pk = NULL; unsigned long tflags; if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) return X509_V_OK; tflags = flags; /* If no EE certificate passed in must be first in chain */ if (x == NULL) { x = sk_X509_value(chain, 0); i = 1; } else i = 0; if (X509_get_version(x) != 2) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; /* Correct error depth */ i = 0; goto end; } pk = X509_get_pubkey(x); /* Check EE key only */ rv = check_suite_b(pk, -1, &tflags); if (rv != X509_V_OK) { /* Correct error depth */ i = 0; goto end; } for(; i < sk_X509_num(chain); i++) { sign_nid = X509_get_signature_nid(x); x = sk_X509_value(chain, i); if (X509_get_version(x) != 2) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; goto end; } EVP_PKEY_free(pk); pk = X509_get_pubkey(x); rv = check_suite_b(pk, sign_nid, &tflags); if (rv != X509_V_OK) goto end; } /* Final check: root CA signature */ rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); end: if (pk) EVP_PKEY_free(pk); if (rv != X509_V_OK) { /* Invalid signature or LOS errors are for previous cert */ if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) i--; /* If we have LOS error and flags changed then we are signing * P-384 with P-256. Use more meaninggul error. */ if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; if (perror_depth) *perror_depth = i; } return rv; } int X509_check_suiteb_crl(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) { int sign_nid; if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) return X509_V_OK; sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); return check_suite_b(pk, sign_nid, &flags); } crypto/x509/x509_txt.c +12 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,18 @@ const char *X509_verify_cert_error_string(long n) return("CRL path validation error"); case X509_V_ERR_PATH_LOOP: return("Path Loop"); case X509_V_ERR_SUITE_B_INVALID_VERSION: return("Suite B: certificate version invalid"); case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: return("Suite B: invalid public key algorithm"); case X509_V_ERR_SUITE_B_INVALID_CURVE: return("Suite B: invalid ECC curve"); case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: return("Suite B: invalid signature algorithm"); case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: return("Suite B: curve not allowed for this LOS"); case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: return("Suite B: cannot sign P-384 with P-256"); default: BIO_snprintf(buf,sizeof buf,"error number %ld",n); Loading Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) New chain verification flags for Suite B levels of security. Check algorithms are acceptable when flags are set in X509_verify_cert. [Steve Henson] *) Make tls1_check_chain return a set of flags indicating checks passed by a certificate chain. Add additional tests to handle client certificates: checks for matching certificate type and issuer name Loading
apps/apps.c +6 −0 Original line number Diff line number Diff line Loading @@ -2376,6 +2376,12 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; else if (!strcmp(arg, "-trusted_first")) flags |= X509_V_FLAG_TRUSTED_FIRST; else if (!strcmp(arg, "-suiteB_128_only")) flags |= X509_V_FLAG_SUITEB_128_LOS_ONLY; else if (!strcmp(arg, "-suiteB_128")) flags |= X509_V_FLAG_SUITEB_128_LOS; else if (!strcmp(arg, "-suiteB_192")) flags |= X509_V_FLAG_SUITEB_192_LOS; else return 0; Loading
crypto/x509/x509.h +5 −0 Original line number Diff line number Diff line Loading @@ -966,6 +966,11 @@ int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); int X509_check_suiteb_chain(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags); int X509_check_suiteb_crl(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); unsigned long X509_issuer_and_serial_hash(X509 *a); Loading
crypto/x509/x509_cmp.c +124 −0 Original line number Diff line number Diff line Loading @@ -341,3 +341,127 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k) return 1; return 0; } /* Check a suite B algorithm is permitted: pass in a public key and * the NID of its signature (or 0 if no signature). The pflags is * a pointer to a flags field which must contain the suite B verification * flags. */ static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) { const EC_GROUP *grp = NULL; int curve_nid; if (pkey && pkey->type == EVP_PKEY_EC) grp = EC_KEY_get0_group(pkey->pkey.ec); if (!grp) return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; curve_nid = EC_GROUP_get_curve_name(grp); /* Check curve is consistent with LOS */ if (curve_nid == NID_secp384r1) /* P-384 */ { /* Check signature algorithm is consistent with * curve. */ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; /* If we encounter P-384 we cannot use P-256 later */ *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; } else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */ { if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; } else return X509_V_ERR_SUITE_B_INVALID_CURVE; return X509_V_OK; } int X509_check_suiteb_chain(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags) { int rv, i, sign_nid; EVP_PKEY *pk = NULL; unsigned long tflags; if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) return X509_V_OK; tflags = flags; /* If no EE certificate passed in must be first in chain */ if (x == NULL) { x = sk_X509_value(chain, 0); i = 1; } else i = 0; if (X509_get_version(x) != 2) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; /* Correct error depth */ i = 0; goto end; } pk = X509_get_pubkey(x); /* Check EE key only */ rv = check_suite_b(pk, -1, &tflags); if (rv != X509_V_OK) { /* Correct error depth */ i = 0; goto end; } for(; i < sk_X509_num(chain); i++) { sign_nid = X509_get_signature_nid(x); x = sk_X509_value(chain, i); if (X509_get_version(x) != 2) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; goto end; } EVP_PKEY_free(pk); pk = X509_get_pubkey(x); rv = check_suite_b(pk, sign_nid, &tflags); if (rv != X509_V_OK) goto end; } /* Final check: root CA signature */ rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); end: if (pk) EVP_PKEY_free(pk); if (rv != X509_V_OK) { /* Invalid signature or LOS errors are for previous cert */ if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) i--; /* If we have LOS error and flags changed then we are signing * P-384 with P-256. Use more meaninggul error. */ if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; if (perror_depth) *perror_depth = i; } return rv; } int X509_check_suiteb_crl(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) { int sign_nid; if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) return X509_V_OK; sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); return check_suite_b(pk, sign_nid, &flags); }
crypto/x509/x509_txt.c +12 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,18 @@ const char *X509_verify_cert_error_string(long n) return("CRL path validation error"); case X509_V_ERR_PATH_LOOP: return("Path Loop"); case X509_V_ERR_SUITE_B_INVALID_VERSION: return("Suite B: certificate version invalid"); case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: return("Suite B: invalid public key algorithm"); case X509_V_ERR_SUITE_B_INVALID_CURVE: return("Suite B: invalid ECC curve"); case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: return("Suite B: invalid signature algorithm"); case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: return("Suite B: curve not allowed for this LOS"); case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: return("Suite B: cannot sign P-384 with P-256"); default: BIO_snprintf(buf,sizeof buf,"error number %ld",n); Loading