3792 lines
154 KiB
Diff
3792 lines
154 KiB
Diff
diff --git a/cmd/certutil/certutil.c b/cmd/certutil/certutil.c
|
|
--- a/cmd/certutil/certutil.c
|
|
+++ b/cmd/certutil/certutil.c
|
|
@@ -298,20 +298,17 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
|
|
if (rv != SECSuccess) {
|
|
PORT_FreeArena(arena, PR_FALSE);
|
|
SECU_PrintError(progName, "unable to set algorithm ID");
|
|
return SECFailure;
|
|
}
|
|
} else {
|
|
/* sigh, we need to create a new SEC_GetSignatureAlgorithOidTag()
|
|
* that takes a public key and one that takes a private key */
|
|
- if (keyType == mldsaKey) {
|
|
- hashAlgTag = pubk->u.mldsa.params;
|
|
- }
|
|
- signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
|
|
+ signAlgTag = SECU_GetSignatureAlgorithmFromPublicKey(pubk, hashAlgTag);
|
|
if (signAlgTag == SEC_OID_UNKNOWN) {
|
|
PORT_FreeArena(arena, PR_FALSE);
|
|
SECU_PrintError(progName, "unknown Key or Hash type");
|
|
return SECFailure;
|
|
}
|
|
rv = SECOID_SetAlgorithmID(arena, &signAlg, signAlgTag, 0);
|
|
if (rv != SECSuccess) {
|
|
PORT_FreeArena(arena, PR_FALSE);
|
|
@@ -2056,39 +2053,16 @@ MakeV1Cert(CERTCertDBHandle *handle,
|
|
}
|
|
if (issuerCert) {
|
|
CERT_DestroyCertificate(issuerCert);
|
|
}
|
|
|
|
return (cert);
|
|
}
|
|
|
|
-/* sigh look up the ml-dsa oid by string */
|
|
-static SECOidTag
|
|
-FindTagFromString(char *cipherString)
|
|
-{
|
|
- SECOidTag tag;
|
|
- SECOidData *oid;
|
|
-
|
|
- /* future enhancement: accept dotted oid spec? */
|
|
-
|
|
- for (tag = 1; (oid = SECOID_FindOIDByTag(tag)) != NULL; tag++) {
|
|
- /* only interested in oids that we actually understand */
|
|
- if (oid->mechanism == CKM_INVALID_MECHANISM) {
|
|
- continue;
|
|
- }
|
|
- if (PORT_Strcasecmp(oid->desc, cipherString) != 0) {
|
|
- continue;
|
|
- }
|
|
- return tag;
|
|
- }
|
|
- return SEC_OID_UNKNOWN;
|
|
-}
|
|
-
|
|
-
|
|
static SECStatus
|
|
SetSignatureAlgorithm(PLArenaPool *arena,
|
|
SECAlgorithmID *signAlg,
|
|
SECAlgorithmID *spkiAlg,
|
|
SECOidTag hashAlgTag,
|
|
SECKEYPrivateKey *privKey,
|
|
PRBool pssSign)
|
|
{
|
|
@@ -2119,72 +2093,23 @@ SetSignatureAlgorithm(PLArenaPool *arena
|
|
}
|
|
rv = SECOID_SetAlgorithmID(arena, signAlg,
|
|
SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
|
|
params);
|
|
if (rv != SECSuccess) {
|
|
SECU_PrintError(progName, "Could not set signature algorithm id.");
|
|
return rv;
|
|
}
|
|
- } else if (privKey->keyType == mldsaKey) {
|
|
- /* sigh, we need toexport SECKEY_GetParameterSet(), for now
|
|
- * just do it inline */
|
|
- /* this is temp code until we fix it correctly upstream. Don't
|
|
- * push this upstream */
|
|
- SECOidTag algID;
|
|
- SECItem item;
|
|
- CK_ULONG paramSet;
|
|
-
|
|
- rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey,
|
|
- CKA_PARAMETER_SET, &item);
|
|
-
|
|
- if (rv != SECSuccess) {
|
|
- SECU_PrintError(progName, "missing parameter set for ml-dsa key.");
|
|
- return SECFailure;
|
|
- }
|
|
- if (item.len != sizeof (paramSet)) {
|
|
- SECU_PrintError(progName, "corrupted parameter set for ml-dsa key.");
|
|
- PORT_Free(item.data);
|
|
- return SECFailure;
|
|
- }
|
|
- paramSet = *(CK_ULONG *)item.data;
|
|
- PORT_Free(item.data);
|
|
- switch (paramSet) {
|
|
- case CKP_ML_DSA_44:
|
|
- algID = FindTagFromString("ML-DSA-44");
|
|
- break;
|
|
- case CKP_ML_DSA_65:
|
|
- algID = FindTagFromString("ML-DSA-65");
|
|
- break;
|
|
- case CKP_ML_DSA_87:
|
|
- algID = FindTagFromString("ML-DSA-87");
|
|
- break;
|
|
- default:
|
|
- algID = SEC_OID_UNKNOWN;
|
|
- break;
|
|
- }
|
|
- if (algID == SEC_OID_UNKNOWN) {
|
|
- PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
- SECU_PrintError(progName, "invalid parameter set for ml-dsa key.");
|
|
- return SECFailure;
|
|
- }
|
|
-
|
|
- rv = SECOID_SetAlgorithmID(arena, signAlg, algID, 0);
|
|
- if (rv != SECSuccess) {
|
|
- SECU_PrintError(progName, "Could not set signature algorithm id.");
|
|
- return rv;
|
|
- }
|
|
} else {
|
|
- KeyType keyType = SECKEY_GetPrivateKeyType(privKey);
|
|
SECOidTag algID;
|
|
|
|
/* first, try to get the ParameterSet from the key, If the
|
|
* key as a parameter set, use it, otherwise fall back to
|
|
* SEC_GetSignatureAlgorithmoidTag */
|
|
- algID = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
|
|
+ algID = SECU_GetSignatureAlgorithmFromPrivateKey(privKey, hashAlgTag);
|
|
if (algID == SEC_OID_UNKNOWN) {
|
|
SECU_PrintError(progName, "Unknown key or hash type for issuer.");
|
|
return SECFailure;
|
|
}
|
|
rv = SECOID_SetAlgorithmID(arena, signAlg, algID, 0);
|
|
if (rv != SECSuccess) {
|
|
SECU_PrintError(progName, "Could not set signature algorithm id.");
|
|
return rv;
|
|
diff --git a/cmd/crmf-cgi/crmfcgi.c b/cmd/crmf-cgi/crmfcgi.c
|
|
--- a/cmd/crmf-cgi/crmfcgi.c
|
|
+++ b/cmd/crmf-cgi/crmfcgi.c
|
|
@@ -377,18 +377,17 @@ createNewCert(CERTCertificate **issuedCe
|
|
rv = addExtensions(newCert, certReq);
|
|
if (rv != NO_ERROR) {
|
|
goto loser;
|
|
}
|
|
issuerPrivKey = PK11_FindKeyByAnyCert(issuerCert, varTable);
|
|
if (issuerPrivKey == NULL) {
|
|
rv = COULD_NOT_FIND_ISSUER_PRIVATE_KEY;
|
|
}
|
|
- signTag = SEC_GetSignatureAlgorithmOidTag(issuerPrivatekey->keytype,
|
|
- SEC_OID_UNKNOWN);
|
|
+ signTag = SECU_GetSignatureAlgorithmFromPrivateKey(issuerPrivatekey, SEC_OID_UNKNOWN);
|
|
if (signTag == SEC_OID_UNKNOWN) {
|
|
rv = UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER;
|
|
goto loser;
|
|
}
|
|
srv = SECOID_SetAlgorithmID(newCert->arena, &newCert->signature,
|
|
signTag, 0);
|
|
if (srv != SECSuccess) {
|
|
rv = ERROR_SETTING_SIGN_ALG;
|
|
diff --git a/cmd/lib/secutil.c b/cmd/lib/secutil.c
|
|
--- a/cmd/lib/secutil.c
|
|
+++ b/cmd/lib/secutil.c
|
|
@@ -3854,16 +3854,94 @@ SECU_StoreCRL(PK11SlotInfo *slot, SECIte
|
|
}
|
|
if (!outFile && !slot) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return SECFailure;
|
|
}
|
|
return SECSuccess;
|
|
}
|
|
|
|
+/* look up the an oid by string */
|
|
+SECOidTag
|
|
+SECU_FindTagFromString(char *cipherString)
|
|
+{
|
|
+ SECOidTag tag;
|
|
+ SECOidData *oid;
|
|
+
|
|
+ /* future enhancement: accept dotted oid spec? */
|
|
+
|
|
+ for (tag = 1; (oid = SECOID_FindOIDByTag(tag)) != NULL; tag++) {
|
|
+ /* only interested in oids that we actually understand */
|
|
+ if (oid->mechanism == CKM_INVALID_MECHANISM) {
|
|
+ continue;
|
|
+ }
|
|
+ if (PORT_Strcasecmp(oid->desc, cipherString) != 0) {
|
|
+ continue;
|
|
+ }
|
|
+ return tag;
|
|
+ }
|
|
+ return SEC_OID_UNKNOWN;
|
|
+}
|
|
+
|
|
+
|
|
+/* sigh, we need toexport SECKEY_GetParameterSet(), for now
|
|
+ * just do it inline */
|
|
+/* this is temp code until we fix it correctly upstream. Don't
|
|
+ * push this upstream */
|
|
+SECOidTag
|
|
+SECU_GetSignatureAlgorithmFromPrivateKey(SECKEYPrivateKey *privKey, SECOidTag hashAlg)
|
|
+{
|
|
+ SECItem item;
|
|
+ CK_ULONG paramSet;
|
|
+ SECStatus rv;
|
|
+
|
|
+ /* don't modify hashAlg if we aren't a DSA key */
|
|
+ if (privKey->keyType != mldsaKey) {
|
|
+ return SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlg);
|
|
+ }
|
|
+
|
|
+ rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey,
|
|
+ CKA_PARAMETER_SET, &item);
|
|
+
|
|
+ if (rv != SECSuccess) {
|
|
+ return SEC_OID_UNKNOWN;
|
|
+ }
|
|
+ if (item.len != sizeof (paramSet)) {
|
|
+ PORT_Free(item.data);
|
|
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
+ return SEC_OID_UNKNOWN;
|
|
+ }
|
|
+ paramSet = *(CK_ULONG *)item.data;
|
|
+ PORT_Free(item.data);
|
|
+ switch (paramSet) {
|
|
+ case CKP_ML_DSA_44:
|
|
+ return SECU_FindTagFromString("ML-DSA-44");
|
|
+ break;
|
|
+ case CKP_ML_DSA_65:
|
|
+ return SECU_FindTagFromString("ML-DSA-65");
|
|
+ break;
|
|
+ case CKP_ML_DSA_87:
|
|
+ return SECU_FindTagFromString("ML-DSA-87");
|
|
+ break;
|
|
+ default:
|
|
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
+ break;
|
|
+ }
|
|
+ return SEC_OID_UNKNOWN;
|
|
+}
|
|
+
|
|
+SECOidTag
|
|
+SECU_GetSignatureAlgorithmFromPublicKey(SECKEYPublicKey *pubKey, SECOidTag hashAlg)
|
|
+{
|
|
+ if (pubKey->keyType == mldsaKey) {
|
|
+ return pubKey->u.mldsa.params;
|
|
+ }
|
|
+ return SEC_GetSignatureAlgorithmOidTag(pubKey->keyType, hashAlg);
|
|
+}
|
|
+
|
|
SECStatus
|
|
SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
|
|
SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode)
|
|
{
|
|
SECItem der;
|
|
SECKEYPrivateKey *caPrivateKey = NULL;
|
|
SECStatus rv;
|
|
PLArenaPool *arena;
|
|
@@ -3879,17 +3957,17 @@ SECU_SignAndEncodeCRL(CERTCertificate *i
|
|
arena = signCrl->arena;
|
|
|
|
caPrivateKey = PK11_FindKeyByAnyCert(issuer, NULL);
|
|
if (caPrivateKey == NULL) {
|
|
*resCode = noKeyFound;
|
|
return SECFailure;
|
|
}
|
|
|
|
- algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, hashAlgTag);
|
|
+ algID = SECU_GetSignatureAlgorithmFromPrivateKey(caPrivateKey, hashAlgTag);
|
|
if (algID == SEC_OID_UNKNOWN) {
|
|
*resCode = noSignatureMatch;
|
|
rv = SECFailure;
|
|
goto done;
|
|
}
|
|
|
|
if (!signCrl->crl.signatureAlg.parameters.data) {
|
|
rv = SECOID_SetAlgorithmID(arena, &signCrl->crl.signatureAlg, algID, 0);
|
|
@@ -4379,16 +4457,19 @@ schemeNameToScheme(const char *name)
|
|
compareScheme(ed448);
|
|
compareScheme(rsa_pss_pss_sha256);
|
|
compareScheme(rsa_pss_pss_sha384);
|
|
compareScheme(rsa_pss_pss_sha512);
|
|
compareScheme(dsa_sha1);
|
|
compareScheme(dsa_sha256);
|
|
compareScheme(dsa_sha384);
|
|
compareScheme(dsa_sha512);
|
|
+ compareScheme(mldsa44);
|
|
+ compareScheme(mldsa65);
|
|
+ compareScheme(mldsa87);
|
|
|
|
#undef compareScheme
|
|
|
|
return ssl_sig_none;
|
|
}
|
|
|
|
SECStatus
|
|
parseSigSchemeList(const char *arg, const SSLSignatureScheme **enabledSigSchemes,
|
|
diff --git a/cmd/lib/secutil.h b/cmd/lib/secutil.h
|
|
--- a/cmd/lib/secutil.h
|
|
+++ b/cmd/lib/secutil.h
|
|
@@ -457,12 +457,18 @@ extern int ffs(unsigned int i);
|
|
#endif
|
|
|
|
/* Finds certificate by searching it in the DB or by examinig file
|
|
* in the local directory. */
|
|
CERTCertificate *
|
|
SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle,
|
|
char *name, PRBool ascii,
|
|
void *pwarg);
|
|
+
|
|
+/* temparary libraries for ml-dsa support */
|
|
+SECOidTag SECu_FindTagFromString(char *cipherString);
|
|
+SECOidTag SECU_GetSignatureAlgorithmFromPrivateKey(SECKEYPrivateKey *privKey, SECOidTag hashAlg);
|
|
+SECOidTag SECU_GetSignatureAlgorithmFromPublicKey(SECKEYPublicKey *privKey, SECOidTag hashAlg);
|
|
+
|
|
#include "secerr.h"
|
|
#include "sslerr.h"
|
|
|
|
#endif /* _SEC_UTIL_H_ */
|
|
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c
|
|
--- a/cmd/selfserv/selfserv.c
|
|
+++ b/cmd/selfserv/selfserv.c
|
|
@@ -156,24 +156,25 @@ static PRLogModuleInfo *lm;
|
|
fflush(stderr); \
|
|
}
|
|
#define VLOG(arg) PR_LOG(lm, PR_LOG_DEBUG, arg)
|
|
|
|
static void
|
|
PrintUsageHeader(const char *progName)
|
|
{
|
|
fprintf(stderr,
|
|
- "Usage: %s -n rsa_nickname -p port [-BDENRZbjlmrsuvx] [-w password]\n"
|
|
+ "Usage: %s -n cert_nickname -p port [-BDENRZbjlmrsuvx] [-w password]\n"
|
|
" [-t threads] [-i pid_file] [-c ciphers] [-Y] [-d dbdir] [-g numblocks]\n"
|
|
" [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n"
|
|
" [-V [min-version]:[max-version]] [-a sni_name]\n"
|
|
" [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n"
|
|
- " [-C SSLCacheEntries] [-S dsa_nickname] [-Q]\n"
|
|
- " [-I groups] [-J signatureschemes] [-e ec_nickname]\n"
|
|
+ " [-C SSLCacheEntries] [-S cert_nickname ] [-Q]\n"
|
|
+ " [-I groups] [-J signatureschemes] [-e cer_nickname]\n"
|
|
" -U [0|1] -H [0|1|2] -W [0|1] [-z externalPsk] -q\n"
|
|
+ " -n is for the primary cert, -e are for additional certs -S is deprecated\n"
|
|
"\n",
|
|
progName);
|
|
}
|
|
|
|
static void
|
|
PrintParameterUsage()
|
|
{
|
|
fputs(
|
|
@@ -234,16 +235,17 @@ PrintParameterUsage()
|
|
"x25519mlkem768, secp256r1mlkem768, secp384r1mlkem1024\n"
|
|
"-J comma separated list of enabled signature schemes in preference order.\n"
|
|
" The following values are valid:\n"
|
|
" rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
|
|
" ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
|
|
" ecdsa_secp521r1_sha512,\n"
|
|
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
|
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
|
+ " mldsa44, mldsa65, mldsa87\n"
|
|
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n"
|
|
"-E enable post-handshake authentication\n"
|
|
" (for TLS 1.3; only has an effect with 3 or more -r options)\n"
|
|
"-x Export and print keying material after successful handshake\n"
|
|
" The argument is a comma separated list of exporters in the form:\n"
|
|
" LABEL[:OUTPUT-LENGTH[:CONTEXT]]\n"
|
|
" where LABEL and CONTEXT can be either a free-form string or\n"
|
|
" a hex string if it is preceded by \"0x\"; OUTPUT-LENGTH\n"
|
|
@@ -2923,17 +2925,17 @@ main(int argc, char **argv)
|
|
}
|
|
if (listen_sock) {
|
|
PR_Close(listen_sock);
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
if (certNicknameIndex == 0) {
|
|
- fprintf(stderr, "Must specify at least one certificate nickname using '-n' (RSA), '-S' (DSA), or 'e' (EC).\n");
|
|
+ fprintf(stderr, "Must specify at least one certificate nickname using '-n' or '-e' or '-S' (deprecated) \n");
|
|
fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
|
|
exit(6);
|
|
}
|
|
|
|
if (port == 0) {
|
|
fprintf(stderr, "Required argument 'port' must be non-zero value\n");
|
|
exit(7);
|
|
}
|
|
diff --git a/cmd/signtool/certgen.c b/cmd/signtool/certgen.c
|
|
--- a/cmd/signtool/certgen.c
|
|
+++ b/cmd/signtool/certgen.c
|
|
@@ -433,17 +433,17 @@ sign_cert(CERTCertificate *cert, SECKEYP
|
|
{
|
|
SECStatus rv;
|
|
|
|
SECItem der2;
|
|
SECItem *result2;
|
|
|
|
SECOidTag alg = SEC_OID_UNKNOWN;
|
|
|
|
- alg = SEC_GetSignatureAlgorithmOidTag(privk->keyType, SEC_OID_UNKNOWN);
|
|
+ alg = SECU_GetSignatureAlgorithmFromPrivateKey(privk, SEC_OID_UNKNOWN);
|
|
if (alg == SEC_OID_UNKNOWN) {
|
|
FatalError("Unknown key type");
|
|
}
|
|
|
|
rv = SECOID_SetAlgorithmID(cert->arena, &cert->signature, alg, 0);
|
|
|
|
if (rv != SECSuccess) {
|
|
PR_fprintf(errorFD, "%s: unable to set signature alg id\n",
|
|
diff --git a/cmd/strsclnt/strsclnt.c b/cmd/strsclnt/strsclnt.c
|
|
--- a/cmd/strsclnt/strsclnt.c
|
|
+++ b/cmd/strsclnt/strsclnt.c
|
|
@@ -169,17 +169,18 @@ Usage(void)
|
|
" This takes a comma separated list of signature schemes in preference\n"
|
|
" order.\n"
|
|
" Possible values are:\n"
|
|
" rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
|
|
" ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
|
|
" ecdsa_secp521r1_sha512,\n"
|
|
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
|
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
|
- " dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n",
|
|
+ " dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n"
|
|
+ " mldsa44, mldsa65, mldsa87\n",
|
|
progName);
|
|
exit(1);
|
|
}
|
|
|
|
static void
|
|
errWarn(char *funcString)
|
|
{
|
|
PRErrorCode perr = PR_GetError();
|
|
diff --git a/cmd/tstclnt/tstclnt.c b/cmd/tstclnt/tstclnt.c
|
|
--- a/cmd/tstclnt/tstclnt.c
|
|
+++ b/cmd/tstclnt/tstclnt.c
|
|
@@ -136,16 +136,19 @@ signatureSchemeName(SSLSignatureScheme s
|
|
strcase(ed448);
|
|
strcase(rsa_pss_pss_sha256);
|
|
strcase(rsa_pss_pss_sha384);
|
|
strcase(rsa_pss_pss_sha512);
|
|
strcase(dsa_sha1);
|
|
strcase(dsa_sha256);
|
|
strcase(dsa_sha384);
|
|
strcase(dsa_sha512);
|
|
+ strcase(mldsa44);
|
|
+ strcase(mldsa65);
|
|
+ strcase(mldsa87);
|
|
#undef strcase
|
|
case ssl_sig_rsa_pkcs1_sha1md5:
|
|
return "RSA PKCS#1 SHA1+MD5";
|
|
default:
|
|
break;
|
|
}
|
|
return "Unknown Scheme";
|
|
}
|
|
@@ -318,17 +321,17 @@ PrintParameterUsage()
|
|
"-I", "", "", "");
|
|
fprintf(stderr, "%-20s Comma separated list of signature schemes in preference order.\n"
|
|
"%-20s The following values are valid:\n"
|
|
"%-20s rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
|
|
"%-20s ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
|
|
"%-20s ecdsa_secp521r1_sha512,\n"
|
|
"%-20s rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
|
"%-20s rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
|
- "%-20s dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n",
|
|
+ "%-20s dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512 mldsa44 mldsa65 mldsa87\n",
|
|
"-J", "", "", "", "", "", "", "");
|
|
fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
|
|
fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
|
|
fprintf(stderr, "%-20s Use Encrypted Client Hello with the given Base64-encoded ECHConfigs\n", "-N");
|
|
fprintf(stderr, "%-20s Enable Encrypted Client Hello GREASEing with the given padding size (0-255) \n", "-i");
|
|
fprintf(stderr, "%-20s Enable post-handshake authentication\n"
|
|
"%-20s for TLS 1.3; need to specify -n\n",
|
|
"-E", "");
|
|
diff --git a/doc/certutil.xml b/doc/certutil.xml
|
|
--- a/doc/certutil.xml
|
|
+++ b/doc/certutil.xml
|
|
@@ -270,17 +270,17 @@ Add one or multiple extensions that cert
|
|
<listitem><para>Pass an input file to the command. Depending on the command option, an input file can be a specific certificate, a certificate request file, or a batch file of commands.</para></listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-k key-type-or-id</term>
|
|
<listitem>
|
|
<para>Specify the type or specific ID of a key.</para>
|
|
<para>
|
|
- The valid key type options are rsa, dsa, ec, or all. The default
|
|
+ The valid key type options are rsa, dsa, ec, mldsa or all. The default
|
|
value is rsa. Specifying the type of key can avoid mistakes caused by
|
|
duplicate nicknames. Giving a key type generates a new key pair;
|
|
giving the ID of an existing key reuses that key pair (which is
|
|
required to renew certificates).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
@@ -311,17 +311,17 @@ Add one or multiple extensions that cert
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-p phone</term>
|
|
<listitem><para>Specify a contact telephone number to include in new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces.</para></listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
- <term>-q pqgfile or curve-name</term>
|
|
+ <term>-q pqgfile or curve-name or ml-dsa-parameter-set</term>
|
|
<listitem>
|
|
<para>Read an alternate PQG value from the specified file when generating DSA key pairs. If this argument is not used, <command>certutil</command> generates its own PQG value. PQG files are created with a separate DSA utility.</para>
|
|
<para>Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519.</para>
|
|
<para>
|
|
If a token is available that supports more curves, the foolowing curves are supported as well:
|
|
sect163k1, nistk163, sect163r1, sect163r2,
|
|
nistb163, sect193r1, sect193r2, sect233k1, nistk233,
|
|
sect233r1, nistb233, sect239k1, sect283k1, nistk283,
|
|
@@ -335,16 +335,17 @@ Add one or multiple extensions that cert
|
|
c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,
|
|
c2tnb191v2, c2tnb191v3,
|
|
c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,
|
|
c2pnb272w1, c2pnb304w1,
|
|
c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,
|
|
secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,
|
|
sect131r1, sect131r2
|
|
</para>
|
|
+ <para>ML-DSA parameter set is one of ml-dsa-44, ml-dsa-65, ml-dsa-87.</para>
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-r </term>
|
|
<listitem><para>Display a certificate's binary DER encoding when listing information about that certificate with the -L option.</para></listitem>
|
|
</varlistentry>
|
|
diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
|
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc
|
|
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
|
@@ -2295,9 +2295,31 @@ INSTANTIATE_TEST_SUITE_P(
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
|
|
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
|
TlsConnectTestBase::kTlsV12,
|
|
::testing::Values(TlsAgent::kServerEcdsa256,
|
|
TlsAgent::kServerEcdsa384),
|
|
::testing::Values(ssl_auth_ecdsa),
|
|
::testing::Values(ssl_sig_ecdsa_sha1)));
|
|
+// ML-DSA is only allowed to be used in TLS 1.3 or greater
|
|
+INSTANTIATE_TEST_SUITE_P(
|
|
+ SignatureSchemeMlDsa44Tls13, TlsSignatureSchemeConfiguration,
|
|
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
|
+ TlsConnectTestBase::kTlsV13,
|
|
+ ::testing::Values(TlsAgent::kServerMlDsa44),
|
|
+ ::testing::Values(ssl_auth_mldsa44),
|
|
+ ::testing::Values(ssl_sig_mldsa44)));
|
|
+INSTANTIATE_TEST_SUITE_P(
|
|
+ SignatureSchemeMlDsa65Tls13, TlsSignatureSchemeConfiguration,
|
|
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
|
+ TlsConnectTestBase::kTlsV13,
|
|
+ ::testing::Values(TlsAgent::kServerMlDsa65),
|
|
+ ::testing::Values(ssl_auth_mldsa65),
|
|
+ ::testing::Values(ssl_sig_mldsa65)));
|
|
+INSTANTIATE_TEST_SUITE_P(
|
|
+ SignatureSchemeMlDsa87Tls13, TlsSignatureSchemeConfiguration,
|
|
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
|
+ TlsConnectTestBase::kTlsV13,
|
|
+ ::testing::Values(TlsAgent::kServerMlDsa87),
|
|
+ ::testing::Values(ssl_auth_mldsa87),
|
|
+ ::testing::Values(ssl_sig_mldsa87)));
|
|
} // namespace nss_test
|
|
diff --git a/gtests/ssl_gtest/tls_agent.cc b/gtests/ssl_gtest/tls_agent.cc
|
|
--- a/gtests/ssl_gtest/tls_agent.cc
|
|
+++ b/gtests/ssl_gtest/tls_agent.cc
|
|
@@ -39,19 +39,25 @@ const std::string TlsAgent::kServerRsaSi
|
|
const std::string TlsAgent::kServerRsaPss = "rsa_pss";
|
|
const std::string TlsAgent::kServerRsaDecrypt = "rsa_decrypt";
|
|
const std::string TlsAgent::kServerEcdsa256 = "ecdsa256";
|
|
const std::string TlsAgent::kServerEcdsa384 = "ecdsa384";
|
|
const std::string TlsAgent::kServerEcdsa521 = "ecdsa521";
|
|
const std::string TlsAgent::kServerEcdhRsa = "ecdh_rsa";
|
|
const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
|
|
const std::string TlsAgent::kServerDsa = "dsa";
|
|
+const std::string TlsAgent::kServerMlDsa44 = "mldsa44";
|
|
+const std::string TlsAgent::kServerMlDsa65 = "mldsa65";
|
|
+const std::string TlsAgent::kServerMlDsa87 = "mldsa87";
|
|
const std::string TlsAgent::kDelegatorEcdsa256 = "delegator_ecdsa256";
|
|
const std::string TlsAgent::kDelegatorRsae2048 = "delegator_rsae2048";
|
|
const std::string TlsAgent::kDelegatorRsaPss2048 = "delegator_rsa_pss2048";
|
|
+const std::string TlsAgent::kDelegatorMlDsa44 = "delegator_mldsa44";
|
|
+const std::string TlsAgent::kDelegatorMlDsa65 = "delegator_mldsa65";
|
|
+const std::string TlsAgent::kDelegatorMlDsa87 = "delegator_mldsa87";
|
|
|
|
static const uint8_t kCannedTls13ServerHello[] = {
|
|
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
|
|
0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
|
|
0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
|
|
0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
|
|
0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
|
|
0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
|
|
diff --git a/gtests/ssl_gtest/tls_agent.h b/gtests/ssl_gtest/tls_agent.h
|
|
--- a/gtests/ssl_gtest/tls_agent.h
|
|
+++ b/gtests/ssl_gtest/tls_agent.h
|
|
@@ -82,19 +82,25 @@ class TlsAgent : public PollTarget {
|
|
static const std::string kServerRsaPss;
|
|
static const std::string kServerRsaDecrypt;
|
|
static const std::string kServerEcdsa256;
|
|
static const std::string kServerEcdsa384;
|
|
static const std::string kServerEcdsa521;
|
|
static const std::string kServerEcdhEcdsa;
|
|
static const std::string kServerEcdhRsa;
|
|
static const std::string kServerDsa;
|
|
+ static const std::string kServerMlDsa44;
|
|
+ static const std::string kServerMlDsa65;
|
|
+ static const std::string kServerMlDsa87;
|
|
static const std::string kDelegatorEcdsa256; // draft-ietf-tls-subcerts
|
|
static const std::string kDelegatorRsae2048; // draft-ietf-tls-subcerts
|
|
static const std::string kDelegatorRsaPss2048; // draft-ietf-tls-subcerts
|
|
+ static const std::string kDelegatorMlDsa44; // draft-ietf-tls-subcerts
|
|
+ static const std::string kDelegatorMlDsa65; // draft-ietf-tls-subcerts
|
|
+ static const std::string kDelegatorMlDsa87; // draft-ietf-tls-subcerts
|
|
|
|
TlsAgent(const std::string& name, Role role, SSLProtocolVariant variant);
|
|
virtual ~TlsAgent();
|
|
|
|
void SetPeer(std::shared_ptr<TlsAgent>& peer) {
|
|
adapter_->SetPeer(peer->adapter_);
|
|
}
|
|
|
|
diff --git a/gtests/ssl_gtest/tls_subcerts_unittest.cc b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
|
--- a/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
|
+++ b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
|
@@ -19,21 +19,23 @@
|
|
|
|
namespace nss_test {
|
|
|
|
#ifndef LTO
|
|
// sigh this construction breaks LTO
|
|
const std::string kEcdsaDelegatorId = TlsAgent::kDelegatorEcdsa256;
|
|
const std::string kRsaeDelegatorId = TlsAgent::kDelegatorRsae2048;
|
|
const std::string kPssDelegatorId = TlsAgent::kDelegatorRsaPss2048;
|
|
+const std::string kMlDsa65DelegatorId = TlsAgent::kDelegatorMlDsa65;
|
|
const std::string kDCId = TlsAgent::kServerEcdsa256;
|
|
#else
|
|
#define kEcdsaDelegatorId TlsAgent::kDelegatorEcdsa256
|
|
#define kRsaeDelegatorId TlsAgent::kDelegatorRsae2048
|
|
#define kPssDelegatorId TlsAgent::kDelegatorRsaPss2048
|
|
+#define kMlDsa65DelegatorId TlsAgent::kDelegatorMlDsa65
|
|
#define kDCId TlsAgent::kServerEcdsa256
|
|
#endif
|
|
const SSLSignatureScheme kDCScheme = ssl_sig_ecdsa_secp256r1_sha256;
|
|
const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */;
|
|
|
|
static void CheckPreliminaryPeerDelegCred(
|
|
const std::shared_ptr<TlsAgent>& client, bool expected,
|
|
PRUint32 key_bits = 0, SSLSignatureScheme sig_scheme = ssl_sig_none) {
|
|
@@ -234,16 +236,63 @@ TEST_P(TlsConnectTls13, DCConnectEcdsaP2
|
|
client_, ssl_delegated_credentials_xtn);
|
|
Connect();
|
|
|
|
EXPECT_TRUE(cfilter->captured());
|
|
CheckPeerDelegCred(client_, true, 256);
|
|
EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
|
}
|
|
|
|
+// Connected with ML-DSA-65, using an ML-DSA-65 SKI and ML-DSA-65 delegation cert.
|
|
+TEST_P(TlsConnectTls13, DCConnectMlDsa65MlDsa65) {
|
|
+ Reset(kMlDsa65DelegatorId);
|
|
+
|
|
+ // Need to enable PSS-PSS, which is not on by default.
|
|
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
|
|
+ ssl_sig_mldsa65};
|
|
+ client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
+ server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
+
|
|
+ client_->EnableDelegatedCredentials();
|
|
+ server_->AddDelegatedCredential(
|
|
+ TlsAgent::kServerMlDsa65, ssl_sig_mldsa65, kDCValidFor, now());
|
|
+
|
|
+ auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
|
|
+ client_, ssl_delegated_credentials_xtn);
|
|
+ Connect();
|
|
+
|
|
+ EXPECT_TRUE(cfilter->captured());
|
|
+ CheckPeerDelegCred(client_, true, ML_DSA_65_PUBLICKEY_LEN*8);
|
|
+ EXPECT_EQ(ssl_sig_mldsa65, client_->info().signatureScheme);
|
|
+}
|
|
+
|
|
+// Connected with ECDSA-P256 using a PSS delegation cert.
|
|
+TEST_P(TlsConnectTls13, DCConnectEcdsaP256MlDsa65) {
|
|
+ Reset(kMlDsa65DelegatorId);
|
|
+
|
|
+ // Need to enable PSS-PSS, which is not on by default.
|
|
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
|
|
+ ssl_sig_mldsa65};
|
|
+ client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
+ server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
+
|
|
+ client_->EnableDelegatedCredentials();
|
|
+ server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
|
|
+ ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
|
|
+ now());
|
|
+
|
|
+ auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
|
|
+ client_, ssl_delegated_credentials_xtn);
|
|
+ Connect();
|
|
+
|
|
+ EXPECT_TRUE(cfilter->captured());
|
|
+ CheckPeerDelegCred(client_, true, 256);
|
|
+ EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
|
+}
|
|
+
|
|
// Simulate the client receiving a DC containing algorithms not advertised.
|
|
// Do this by tweaking the client's supported sigSchemes after the CH.
|
|
TEST_P(TlsConnectTls13, DCReceiveUnadvertisedScheme) {
|
|
Reset(kEcdsaDelegatorId);
|
|
static const SSLSignatureScheme kClientSchemes[] = {
|
|
ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384};
|
|
static const SSLSignatureScheme kServerSchemes[] = {
|
|
ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_ecdsa_secp256r1_sha256};
|
|
@@ -733,11 +782,29 @@ TEST_F(DCDelegation, DCDelegations) {
|
|
cert.get(), priv.get(), pub_ecdsa.get(),
|
|
ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
|
|
EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
|
EXPECT_EQ(SECFailure,
|
|
SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
|
|
ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
|
|
now, &dc));
|
|
EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
|
+ ScopedSECKEYPublicKey pub_mldsa;
|
|
+ ScopedSECKEYPrivateKey priv_mldsa;
|
|
+ ASSERT_TRUE(TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerMlDsa65,
|
|
+ &pub_mldsa, &priv_mldsa));
|
|
+ EXPECT_EQ(SECFailure,
|
|
+ SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
|
+ ssl_sig_rsa_pss_rsae_sha256, kDCValidFor,
|
|
+ now, &dc));
|
|
+ EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
|
+ EXPECT_EQ(SECFailure, SSL_DelegateCredential(
|
|
+ cert.get(), priv.get(), pub_mldsa.get(),
|
|
+ ssl_sig_mldsa44, kDCValidFor, now, &dc));
|
|
+ EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
|
+ EXPECT_EQ(SECSuccess,
|
|
+ SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
|
+ ssl_sig_mldsa65, kDCValidFor,
|
|
+ now, &dc));
|
|
+ dc.Reset();
|
|
}
|
|
|
|
} // namespace nss_test
|
|
diff --git a/lib/cryptohi/secsign.c b/lib/cryptohi/secsign.c
|
|
--- a/lib/cryptohi/secsign.c
|
|
+++ b/lib/cryptohi/secsign.c
|
|
@@ -764,28 +764,24 @@ SEC_GetSignatureAlgorithmOidTag(KeyType
|
|
return sigTag;
|
|
}
|
|
|
|
static SECItem *
|
|
sec_CreateRSAPSSParameters(PLArenaPool *arena,
|
|
SECItem *result,
|
|
SECOidTag hashAlgTag,
|
|
const SECItem *params,
|
|
- const SECKEYPrivateKey *key)
|
|
+ int modBytes)
|
|
{
|
|
SECKEYRSAPSSParams pssParams;
|
|
- int modBytes, hashLength;
|
|
+ int hashLength;
|
|
unsigned long saltLength;
|
|
PRBool defaultSHA1 = PR_FALSE;
|
|
SECStatus rv;
|
|
|
|
- if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
|
|
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
|
- return NULL;
|
|
- }
|
|
|
|
PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
|
|
|
if (params && params->data) {
|
|
/* The parameters field should either be empty or contain
|
|
* valid RSA-PSS parameters */
|
|
PORT_Assert(!(params->len == 2 &&
|
|
params->data[0] == SEC_ASN1_NULL &&
|
|
@@ -808,21 +804,28 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
|
return NULL;
|
|
}
|
|
if (trailerField != 1) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
- modBytes = PK11_GetPrivateModulusLen((SECKEYPrivateKey *)key);
|
|
|
|
/* Determine the hash algorithm to use, based on hashAlgTag and
|
|
- * pssParams.hashAlg; there are four cases */
|
|
- if (hashAlgTag != SEC_OID_UNKNOWN) {
|
|
+ * pssParams.hashAlg; there are 6 cases.
|
|
+ * case:
|
|
+ * 1) we did not specify any parameters but we did specifi
|
|
+ * a hashAlgTag. Use the specified hash algtag. This is the fall
|
|
+ * through case (none of the if's trigger).
|
|
+ * 2) We have params and we have a specified hashAlgTag from
|
|
+ * the app and the hash alg is in the parameters, make sure that the
|
|
+ * hashAlgTag specified by the appication matches.
|
|
+ * 3) Same as 2 except the algorithm is not specified by the */
|
|
+ if (params && (hashAlgTag != SEC_OID_UNKNOWN)) {
|
|
SECOidTag tag = SEC_OID_UNKNOWN;
|
|
|
|
if (pssParams.hashAlg) {
|
|
tag = SECOID_GetAlgorithmTag(pssParams.hashAlg);
|
|
} else if (defaultSHA1) {
|
|
tag = SEC_OID_SHA1;
|
|
}
|
|
|
|
@@ -897,16 +900,18 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
|
&saltLength);
|
|
if (rv != SECSuccess) {
|
|
return NULL;
|
|
}
|
|
|
|
/* The specified salt length is too long */
|
|
if (saltLength > (unsigned long)(modBytes - hashLength - 2)) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
+
|
|
+
|
|
return NULL;
|
|
}
|
|
} else if (defaultSHA1) {
|
|
saltLength = 20;
|
|
}
|
|
|
|
/* Fill in the parameters */
|
|
if (pssParams.hashAlg) {
|
|
@@ -983,22 +988,57 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
|
SECItem *
|
|
SEC_CreateSignatureAlgorithmParameters(PLArenaPool *arena,
|
|
SECItem *result,
|
|
SECOidTag signAlgTag,
|
|
SECOidTag hashAlgTag,
|
|
const SECItem *params,
|
|
const SECKEYPrivateKey *key)
|
|
{
|
|
+ int modBytes;
|
|
switch (signAlgTag) {
|
|
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
|
+ if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
|
+ return NULL;
|
|
+ }
|
|
+ modBytes = PK11_GetPrivateModulusLen((SECKEYPrivateKey *)key);
|
|
return sec_CreateRSAPSSParameters(arena, result,
|
|
- hashAlgTag, params, key);
|
|
+ hashAlgTag, params, modBytes);
|
|
default:
|
|
if (params == NULL)
|
|
return NULL;
|
|
if (result == NULL)
|
|
result = SECITEM_AllocItem(arena, NULL, 0);
|
|
if (SECITEM_CopyItem(arena, result, params) != SECSuccess)
|
|
return NULL;
|
|
return result;
|
|
}
|
|
}
|
|
+
|
|
+SECItem *
|
|
+SEC_CreateVerifySignatureAlgorithmParameters(PLArenaPool *arena,
|
|
+ SECItem *result,
|
|
+ SECOidTag signAlgTag,
|
|
+ SECOidTag hashAlgTag,
|
|
+ const SECItem *params,
|
|
+ const SECKEYPublicKey *key)
|
|
+{
|
|
+ int modBytes;
|
|
+ switch (signAlgTag) {
|
|
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
|
+ if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
|
+ return NULL;
|
|
+ }
|
|
+ modBytes = key->u.rsa.modulus.len;
|
|
+ return sec_CreateRSAPSSParameters(arena, result,
|
|
+ hashAlgTag, params, modBytes);
|
|
+ default:
|
|
+ if (params == NULL)
|
|
+ return NULL;
|
|
+ if (result == NULL)
|
|
+ result = SECITEM_AllocItem(arena, NULL, 0);
|
|
+ if (SECITEM_CopyItem(arena, result, params) != SECSuccess)
|
|
+ return NULL;
|
|
+ return result;
|
|
+ }
|
|
+}
|
|
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
|
|
--- a/lib/ssl/ssl3con.c
|
|
+++ b/lib/ssl/ssl3con.c
|
|
@@ -31,16 +31,17 @@
|
|
#include "pratom.h"
|
|
#include "prthread.h"
|
|
#include "nss.h"
|
|
#include "nssoptions.h"
|
|
|
|
#include "pk11func.h"
|
|
#include "secmod.h"
|
|
#include "blapi.h"
|
|
+#include "secmodti.h" /* for ML_DSA_OIDS, not needed upstream */
|
|
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
|
|
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
|
|
PK11SlotInfo *serverKeySlot);
|
|
static SECStatus ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms,
|
|
PK11SymKey **msp);
|
|
@@ -66,16 +67,17 @@ static SECStatus ssl3_HandlePostHelloHan
|
|
PRUint32 length);
|
|
static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
|
|
static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType);
|
|
static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash);
|
|
PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme);
|
|
PRBool ssl_IsRsaeSignatureScheme(SSLSignatureScheme scheme);
|
|
PRBool ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme);
|
|
PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme);
|
|
+PRBool ssl_IsMlDsaSignatureScheme(SSLSignatureScheme scheme);
|
|
static SECStatus ssl3_UpdateDefaultHandshakeHashes(sslSocket *ss,
|
|
const unsigned char *b,
|
|
unsigned int l);
|
|
const PRUint32 kSSLSigSchemePolicy =
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_ANY_SIGNATURE;
|
|
|
|
const PRUint8 ssl_hello_retry_random[] = {
|
|
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
|
@@ -200,17 +202,20 @@ static const SSLSignatureScheme defaultS
|
|
ssl_sig_rsa_pss_rsae_sha512,
|
|
ssl_sig_rsa_pkcs1_sha256,
|
|
ssl_sig_rsa_pkcs1_sha384,
|
|
ssl_sig_rsa_pkcs1_sha512,
|
|
ssl_sig_rsa_pkcs1_sha1,
|
|
ssl_sig_dsa_sha256,
|
|
ssl_sig_dsa_sha384,
|
|
ssl_sig_dsa_sha512,
|
|
- ssl_sig_dsa_sha1
|
|
+ ssl_sig_dsa_sha1,
|
|
+ ssl_sig_mldsa44,
|
|
+ ssl_sig_mldsa65,
|
|
+ ssl_sig_mldsa87,
|
|
};
|
|
PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureSchemes) <=
|
|
MAX_SIGNATURE_SCHEMES);
|
|
|
|
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
|
|
*/
|
|
#ifdef DEBUG
|
|
void
|
|
@@ -358,17 +363,20 @@ static const CK_MECHANISM_TYPE auth_alg_
|
|
CKM_DSA, /* ? _SHA1 */ /* ssl_auth_dsa */
|
|
CKM_INVALID_MECHANISM, /* ssl_auth_kea (unused) */
|
|
CKM_ECDSA, /* ssl_auth_ecdsa */
|
|
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_rsa */
|
|
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_ecdsa */
|
|
CKM_RSA_PKCS, /* ssl_auth_rsa_sign */
|
|
CKM_RSA_PKCS_PSS, /* ssl_auth_rsa_pss */
|
|
CKM_NSS_HKDF_SHA256, /* ssl_auth_psk (just check for HKDF) */
|
|
- CKM_INVALID_MECHANISM /* ssl_auth_tls13_any */
|
|
+ CKM_INVALID_MECHANISM, /* ssl_auth_tls13_any */
|
|
+ CKM_ML_DSA, /* ssl_auth_mldsa (same mech for each) */
|
|
+ CKM_ML_DSA, /* ssl_auth_mldsa (key determines the*/
|
|
+ CKM_ML_DSA, /* ssl_auth_mldsa parameter set) */
|
|
};
|
|
PR_STATIC_ASSERT(PR_ARRAY_SIZE(auth_alg_defs) == ssl_auth_size);
|
|
|
|
static const CK_MECHANISM_TYPE kea_alg_defs[] = {
|
|
CKM_INVALID_MECHANISM, /* ssl_kea_null */
|
|
CKM_RSA_PKCS, /* ssl_kea_rsa */
|
|
CKM_DH_PKCS_DERIVE, /* ssl_kea_dh */
|
|
CKM_INVALID_MECHANISM, /* ssl_kea_fortezza (unused) */
|
|
@@ -758,16 +766,23 @@ ssl_KEAEnabled(const sslSocket *ss, SSLK
|
|
|
|
static PRBool
|
|
ssl_HasCert(const sslSocket *ss, PRUint16 maxVersion, SSLAuthType authType)
|
|
{
|
|
PRCList *cursor;
|
|
if (authType == ssl_auth_null || authType == ssl_auth_psk || authType == ssl_auth_tls13_any) {
|
|
return PR_TRUE;
|
|
}
|
|
+ /* mldsa is only supported in TLS 1.3 or greater */
|
|
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3 &&
|
|
+ (authType == ssl_auth_mldsa44 ||
|
|
+ authType == ssl_auth_mldsa65 ||
|
|
+ authType == ssl_auth_mldsa87)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
for (cursor = PR_NEXT_LINK(&ss->serverCerts);
|
|
cursor != &ss->serverCerts;
|
|
cursor = PR_NEXT_LINK(cursor)) {
|
|
sslServerCert *cert = (sslServerCert *)cursor;
|
|
if (!cert->serverKeyPair ||
|
|
!cert->serverKeyPair->privKey ||
|
|
!cert->serverCertChain ||
|
|
!SSL_CERT_IS(cert, authType)) {
|
|
@@ -803,16 +818,21 @@ ssl_HasCert(const sslSocket *ss, PRUint1
|
|
static PRBool
|
|
ssl_SchemePolicyOK(SSLSignatureScheme scheme, PRUint32 require)
|
|
{
|
|
/* Hash policy. */
|
|
PRUint32 policy;
|
|
SECOidTag hashOID = ssl3_HashTypeToOID(ssl_SignatureSchemeToHashType(scheme));
|
|
SECOidTag sigOID;
|
|
|
|
+#ifndef NSS_ENABLE_ML_DSA
|
|
+ if (ssl_IsMlDsaSignatureScheme(scheme)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+#endif
|
|
/* policy bits needed to enable a SignatureScheme */
|
|
SECStatus rv = NSS_GetAlgorithmPolicy(hashOID, &policy);
|
|
if (rv == SECSuccess &&
|
|
(policy & require) != require) {
|
|
return PR_FALSE;
|
|
}
|
|
|
|
/* ssl_SignatureSchemeToAuthType reports rsa for rsa_pss_rsae, but we
|
|
@@ -830,17 +850,17 @@ ssl_SchemePolicyOK(SSLSignatureScheme sc
|
|
return PR_FALSE;
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
/* Check that a signature scheme is accepted.
|
|
* Both by policy and by having a token that supports it. */
|
|
static PRBool
|
|
-ssl_SignatureSchemeAccepted(PRUint16 minVersion,
|
|
+ssl_SignatureSchemeAccepted(PRUint16 minVersion, PRUint16 maxVersion,
|
|
SSLSignatureScheme scheme,
|
|
PRBool forCert)
|
|
{
|
|
/* Disable RSA-PSS schemes if there are no tokens to verify them. */
|
|
if (ssl_IsRsaPssSignatureScheme(scheme)) {
|
|
if (!PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) {
|
|
return PR_FALSE;
|
|
}
|
|
@@ -852,16 +872,21 @@ ssl_SignatureSchemeAccepted(PRUint16 min
|
|
if (minVersion >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
return PR_FALSE;
|
|
}
|
|
} else if (ssl_IsDsaSignatureScheme(scheme)) {
|
|
/* DSA: not in TLS 1.3, and check policy. */
|
|
if (minVersion >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
return PR_FALSE;
|
|
}
|
|
+ } else if (ssl_IsMlDsaSignatureScheme(scheme)) {
|
|
+ /* MLDSA: limit ml-dsa if we don't support TLS 1.3. */
|
|
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
}
|
|
|
|
return ssl_SchemePolicyOK(scheme, kSSLSigSchemePolicy);
|
|
}
|
|
|
|
static SECStatus
|
|
ssl_CheckSignatureSchemes(sslSocket *ss)
|
|
{
|
|
@@ -887,17 +912,17 @@ ssl_CheckSignatureSchemes(sslSocket *ss)
|
|
if (!foundCert) {
|
|
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
|
|
return SECFailure;
|
|
}
|
|
}
|
|
|
|
/* Ensure that there is a signature scheme that can be accepted.*/
|
|
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
- if (ssl_SignatureSchemeAccepted(ss->vrange.min,
|
|
+ if (ssl_SignatureSchemeAccepted(ss->vrange.min, ss->vrange.max,
|
|
ss->ssl3.signatureSchemes[i],
|
|
PR_FALSE /* forCert */)) {
|
|
return SECSuccess;
|
|
}
|
|
}
|
|
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
|
|
return SECFailure;
|
|
}
|
|
@@ -918,17 +943,18 @@ ssl_HasSignatureScheme(const sslSocket *
|
|
return PR_TRUE;
|
|
}
|
|
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
SSLSignatureScheme scheme = ss->ssl3.signatureSchemes[i];
|
|
SSLAuthType schemeAuthType = ssl_SignatureSchemeToAuthType(scheme);
|
|
PRBool acceptable = authType == schemeAuthType ||
|
|
(schemeAuthType == ssl_auth_rsa_pss &&
|
|
authType == ssl_auth_rsa_sign);
|
|
- if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme, PR_FALSE /* forCert */)) {
|
|
+ if (acceptable && ssl_SignatureSchemeAccepted(ss->version,
|
|
+ ss->version, scheme, PR_FALSE /* forCert */)) {
|
|
return PR_TRUE;
|
|
}
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
/* Initialize the suite->isPresent value for config_match
|
|
* Returns count of enabled ciphers supported by extant tokens,
|
|
@@ -1228,17 +1254,18 @@ ssl3_GetNewRandom(SSL3Random random)
|
|
|
|
rv = PK11_GenerateRandom(random, SSL3_RANDOM_LENGTH);
|
|
if (rv != SECSuccess) {
|
|
ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
-SECStatus
|
|
+/* this only implements TLS 1.2 and earlier signatures */
|
|
+static SECStatus
|
|
ssl3_SignHashesWithPrivKey(SSL3Hashes *hash, SECKEYPrivateKey *key,
|
|
SSLSignatureScheme scheme, PRBool isTls, SECItem *buf)
|
|
{
|
|
SECStatus rv = SECFailure;
|
|
PRBool doDerEncode = PR_FALSE;
|
|
PRBool useRsaPss = ssl_IsRsaPssSignatureScheme(scheme);
|
|
SECItem hashItem;
|
|
|
|
@@ -1289,18 +1316,19 @@ ssl3_SignHashesWithPrivKey(SSL3Hashes *h
|
|
SECItem pssParamsItem = { siBuffer,
|
|
(unsigned char *)&pssParams,
|
|
sizeof(pssParams) };
|
|
|
|
if (signatureLen <= 0) {
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
goto done;
|
|
}
|
|
- /* since we are calling PK11_SignWithMechanism directly, we need to check the
|
|
- * key policy ourselves (which is already checked in SGN_Digest */
|
|
+ /* since we are calling PK11_SignWithMechanism directly, we need to
|
|
+ * check the key policy ourselves (which is already checked in
|
|
+ * SGN_Digest */
|
|
rv = NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optval);
|
|
if ((rv == SECSuccess) &&
|
|
((optval & NSS_KEY_SIZE_POLICY_SIGN_FLAG) == NSS_KEY_SIZE_POLICY_SIGN_FLAG)) {
|
|
rv = SECKEY_EnforceKeySize(key->keyType, SECKEY_PrivateKeyStrengthInBits(key),
|
|
SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
|
|
if (rv != SECSuccess) {
|
|
goto done; /* error code already set */
|
|
}
|
|
@@ -1365,18 +1393,19 @@ ssl3_SignHashes(sslSocket *ss, SSL3Hashe
|
|
if (ss->sec.isServer) {
|
|
ss->sec.signatureScheme = scheme;
|
|
ss->sec.authType = ssl_SignatureSchemeToAuthType(scheme);
|
|
}
|
|
|
|
return SECSuccess;
|
|
}
|
|
|
|
-/* Called from ssl3_VerifySignedHashes and tls13_HandleCertificateVerify. */
|
|
-SECStatus
|
|
+/* Called from ssl3_VerifySignedHashes */
|
|
+/* this only implements TLS 1.2 and earlier signatures */
|
|
+static SECStatus
|
|
ssl_VerifySignedHashesWithPubKey(sslSocket *ss, SECKEYPublicKey *key,
|
|
SSLSignatureScheme scheme,
|
|
SSL3Hashes *hash, SECItem *buf)
|
|
{
|
|
SECItem *signature = NULL;
|
|
SECStatus rv = SECFailure;
|
|
SECItem hashItem;
|
|
SECOidTag encAlg;
|
|
@@ -3407,16 +3436,17 @@ ssl3_GetHashMechanismByHashType(SSLHashT
|
|
case ssl_hash_sha384:
|
|
return CKM_SHA384;
|
|
case ssl_hash_sha256:
|
|
case ssl_hash_none:
|
|
/* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
|
|
return CKM_SHA256;
|
|
case ssl_hash_sha1:
|
|
return CKM_SHA_1;
|
|
+ /* don't return a mechansim for ml_dsa hashes */
|
|
default:
|
|
PORT_Assert(0);
|
|
}
|
|
return CKM_SHA256;
|
|
}
|
|
|
|
/* Function valid for >= TLS 1.2, only. */
|
|
static CK_MECHANISM_TYPE
|
|
@@ -4345,16 +4375,29 @@ ssl3_HashTypeToOID(SSLHashType hashType)
|
|
case ssl_hash_sha1:
|
|
return SEC_OID_SHA1;
|
|
case ssl_hash_sha256:
|
|
return SEC_OID_SHA256;
|
|
case ssl_hash_sha384:
|
|
return SEC_OID_SHA384;
|
|
case ssl_hash_sha512:
|
|
return SEC_OID_SHA512;
|
|
+ /* ml-dsa has it's own has algorithm,
|
|
+ * if we are using an external hash,
|
|
+ * we need to fail (at least until
|
|
+ * we get mu support). Fortunately
|
|
+ * mldsa is only supported in TLS 1.3
|
|
+ * and can do full hash and sign in
|
|
+ * the TLS 1.3 protocol */
|
|
+ case ssl_hash_mldsa44:
|
|
+ return SEC_OID_ML_DSA_44;
|
|
+ case ssl_hash_mldsa65:
|
|
+ return SEC_OID_ML_DSA_65;
|
|
+ case ssl_hash_mldsa87:
|
|
+ return SEC_OID_ML_DSA_87;
|
|
default:
|
|
break;
|
|
}
|
|
return SEC_OID_UNKNOWN;
|
|
}
|
|
|
|
SECOidTag
|
|
ssl3_AuthTypeToOID(SSLAuthType authType)
|
|
@@ -4363,16 +4406,22 @@ ssl3_AuthTypeToOID(SSLAuthType authType)
|
|
case ssl_auth_rsa_sign:
|
|
return SEC_OID_PKCS1_RSA_ENCRYPTION;
|
|
case ssl_auth_rsa_pss:
|
|
return SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
|
|
case ssl_auth_ecdsa:
|
|
return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
|
case ssl_auth_dsa:
|
|
return SEC_OID_ANSIX9_DSA_SIGNATURE;
|
|
+ case ssl_auth_mldsa44:
|
|
+ return SEC_OID_ML_DSA_44;
|
|
+ case ssl_auth_mldsa65:
|
|
+ return SEC_OID_ML_DSA_65;
|
|
+ case ssl_auth_mldsa87:
|
|
+ return SEC_OID_ML_DSA_87;
|
|
default:
|
|
break;
|
|
}
|
|
/* shouldn't ever get there */
|
|
PORT_Assert(0);
|
|
return SEC_OID_UNKNOWN;
|
|
}
|
|
|
|
@@ -4397,16 +4446,22 @@ ssl_SignatureSchemeToHashType(SSLSignatu
|
|
case ssl_sig_dsa_sha384:
|
|
return ssl_hash_sha384;
|
|
case ssl_sig_rsa_pkcs1_sha512:
|
|
case ssl_sig_ecdsa_secp521r1_sha512:
|
|
case ssl_sig_rsa_pss_rsae_sha512:
|
|
case ssl_sig_rsa_pss_pss_sha512:
|
|
case ssl_sig_dsa_sha512:
|
|
return ssl_hash_sha512;
|
|
+ case ssl_sig_mldsa44:
|
|
+ return ssl_hash_mldsa44;
|
|
+ case ssl_sig_mldsa65:
|
|
+ return ssl_hash_mldsa65;
|
|
+ case ssl_sig_mldsa87:
|
|
+ return ssl_hash_mldsa87;
|
|
case ssl_sig_rsa_pkcs1_sha1md5:
|
|
return ssl_hash_none; /* Special for TLS 1.0/1.1. */
|
|
case ssl_sig_none:
|
|
case ssl_sig_ed25519:
|
|
case ssl_sig_ed448:
|
|
break;
|
|
}
|
|
PORT_Assert(0);
|
|
@@ -4451,16 +4506,20 @@ ssl_SignatureSchemeValid(SSLSignatureSch
|
|
return PR_FALSE;
|
|
}
|
|
if (ssl_IsDsaSignatureScheme(scheme)) {
|
|
return PR_FALSE;
|
|
}
|
|
/* With TLS 1.3, EC keys should have been selected based on calling
|
|
* ssl_SignatureSchemeFromSpki(), reject them otherwise. */
|
|
return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
|
+ } else {
|
|
+ if (ssl_IsMlDsaSignatureScheme(scheme)) {
|
|
+ return PR_FALSE;
|
|
+ }
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
static SECStatus
|
|
ssl_SignatureSchemeFromPssSpki(const CERTSubjectPublicKeyInfo *spki,
|
|
SSLSignatureScheme *scheme)
|
|
{
|
|
@@ -4538,37 +4597,65 @@ ssl_SignatureSchemeFromEcSpki(const CERT
|
|
return SECSuccess;
|
|
default:
|
|
break;
|
|
}
|
|
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
|
|
return SECFailure;
|
|
}
|
|
|
|
+
|
|
+/* some schmemes match 1 for 1 to oids, for those schemes, we
|
|
+ * can return the oid directly. If this function return ssl_sig_none,
|
|
+ * it means the oid doen't match a scheme or matches more than one
|
|
+ * scheme */
|
|
+SSLSignatureScheme
|
|
+ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag)
|
|
+{
|
|
+ switch (tag) {
|
|
+ case SEC_OID_ML_DSA_44:
|
|
+ return ssl_sig_mldsa44;
|
|
+ case SEC_OID_ML_DSA_65:
|
|
+ return ssl_sig_mldsa65;
|
|
+ case SEC_OID_ML_DSA_87:
|
|
+ return ssl_sig_mldsa87;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ return ssl_sig_none;
|
|
+}
|
|
+
|
|
+
|
|
/* Newer signature schemes are designed so that a single SPKI can be used with
|
|
* that scheme. This determines that scheme from the SPKI. If the SPKI doesn't
|
|
* have a single scheme, |*scheme| is set to ssl_sig_none. */
|
|
SECStatus
|
|
ssl_SignatureSchemeFromSpki(const CERTSubjectPublicKeyInfo *spki,
|
|
PRBool isTls13, SSLSignatureScheme *scheme)
|
|
{
|
|
SECOidTag spkiOid = SECOID_GetAlgorithmTag(&spki->algorithm);
|
|
|
|
- if (spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
|
|
- return ssl_SignatureSchemeFromPssSpki(spki, scheme);
|
|
- }
|
|
-
|
|
- /* Only do this lookup for TLS 1.3, where the scheme can be determined from
|
|
- * the SPKI alone because the ECDSA key size determines the hash. Earlier
|
|
- * TLS versions allow the same EC key to be used with different hashes. */
|
|
- if (isTls13 && spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
|
|
- return ssl_SignatureSchemeFromEcSpki(spki, scheme);
|
|
- }
|
|
-
|
|
+ /* default */
|
|
*scheme = ssl_sig_none;
|
|
+ switch (spkiOid) {
|
|
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
|
+ return ssl_SignatureSchemeFromPssSpki(spki, scheme);
|
|
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
|
+ /* Only do this lookup for TLS 1.3, where the scheme can be
|
|
+ * determined from the SPKI alone because the ECDSA key size
|
|
+ * determines the hash. Earlier TLS versions allow the same
|
|
+ * EC key to be used with different hashes. */
|
|
+ if (isTls13) {
|
|
+ return ssl_SignatureSchemeFromEcSpki(spki, scheme);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ *scheme = ssl_SignatureSchemeFromPublicKeyOid(spkiOid);
|
|
+ break;
|
|
+ }
|
|
return SECSuccess;
|
|
}
|
|
|
|
/* Check that a signature scheme is enabled by configuration. */
|
|
PRBool
|
|
ssl_SignatureSchemeEnabled(const sslSocket *ss, SSLSignatureScheme scheme)
|
|
{
|
|
unsigned int i;
|
|
@@ -4664,16 +4751,19 @@ ssl_IsSupportedSignatureScheme(SSLSignat
|
|
case ssl_sig_rsa_pss_rsae_sha384:
|
|
case ssl_sig_rsa_pss_rsae_sha512:
|
|
case ssl_sig_rsa_pss_pss_sha256:
|
|
case ssl_sig_rsa_pss_pss_sha384:
|
|
case ssl_sig_rsa_pss_pss_sha512:
|
|
case ssl_sig_ecdsa_secp256r1_sha256:
|
|
case ssl_sig_ecdsa_secp384r1_sha384:
|
|
case ssl_sig_ecdsa_secp521r1_sha512:
|
|
+ case ssl_sig_mldsa44:
|
|
+ case ssl_sig_mldsa65:
|
|
+ case ssl_sig_mldsa87:
|
|
case ssl_sig_dsa_sha1:
|
|
case ssl_sig_dsa_sha256:
|
|
case ssl_sig_dsa_sha384:
|
|
case ssl_sig_dsa_sha512:
|
|
case ssl_sig_ecdsa_sha1:
|
|
return ssl_SchemePolicyOK(scheme, kSSLSigSchemePolicy);
|
|
break;
|
|
|
|
@@ -4746,16 +4836,31 @@ ssl_IsDsaSignatureScheme(SSLSignatureSch
|
|
return PR_TRUE;
|
|
|
|
default:
|
|
return PR_FALSE;
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
+PRBool
|
|
+ssl_IsMlDsaSignatureScheme(SSLSignatureScheme scheme)
|
|
+{
|
|
+ switch (scheme) {
|
|
+ case ssl_sig_mldsa44:
|
|
+ case ssl_sig_mldsa65:
|
|
+ case ssl_sig_mldsa87:
|
|
+ return PR_TRUE;
|
|
+
|
|
+ default:
|
|
+ return PR_FALSE;
|
|
+ }
|
|
+ return PR_FALSE;
|
|
+}
|
|
+
|
|
SSLAuthType
|
|
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
|
|
{
|
|
switch (scheme) {
|
|
case ssl_sig_rsa_pkcs1_sha1:
|
|
case ssl_sig_rsa_pkcs1_sha1md5:
|
|
case ssl_sig_rsa_pkcs1_sha256:
|
|
case ssl_sig_rsa_pkcs1_sha384:
|
|
@@ -4769,16 +4874,22 @@ ssl_SignatureSchemeToAuthType(SSLSignatu
|
|
case ssl_sig_rsa_pss_pss_sha384:
|
|
case ssl_sig_rsa_pss_pss_sha512:
|
|
return ssl_auth_rsa_pss;
|
|
case ssl_sig_ecdsa_secp256r1_sha256:
|
|
case ssl_sig_ecdsa_secp384r1_sha384:
|
|
case ssl_sig_ecdsa_secp521r1_sha512:
|
|
case ssl_sig_ecdsa_sha1:
|
|
return ssl_auth_ecdsa;
|
|
+ case ssl_sig_mldsa44:
|
|
+ return ssl_auth_mldsa44;
|
|
+ case ssl_sig_mldsa65:
|
|
+ return ssl_auth_mldsa65;
|
|
+ case ssl_sig_mldsa87:
|
|
+ return ssl_auth_mldsa87;
|
|
case ssl_sig_dsa_sha1:
|
|
case ssl_sig_dsa_sha256:
|
|
case ssl_sig_dsa_sha384:
|
|
case ssl_sig_dsa_sha512:
|
|
return ssl_auth_dsa;
|
|
|
|
default:
|
|
PORT_Assert(0);
|
|
@@ -5852,28 +5963,78 @@ ssl_FindIndexByWrapMechanism(CK_MECHANIS
|
|
return SECSuccess;
|
|
}
|
|
}
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
+/* mldsa server private key cannot be used directly in
|
|
+ * a key exchange. Instead we'll sign the fixed value
|
|
+ * use it in a PBE. This will work with any signature scheme
|
|
+ * with a deterministic signature */
|
|
+#define SSL_SIG_KEY "NSS Session Cashe Ks Init String"
|
|
+static PK11SymKey *
|
|
+ssl_getSigKs(SECKEYPrivateKey *svrPrivKey, CK_MECHANISM_TYPE mechanism,
|
|
+ CK_MECHANISM_TYPE masterWrapMech, void *pwArg)
|
|
+{
|
|
+ const char *sigKey = SSL_SIG_KEY;
|
|
+ SECItem msg = { siBuffer, (unsigned char *)sigKey, sizeof(sigKey) };
|
|
+ /* set to the the size of the largest signature supported. currently
|
|
+ * ml_dsa. If This value is to small, PK11_SignWithMechanism will
|
|
+ * safely fail below without generating the signature */
|
|
+ unsigned char sigBuf[MAX_ML_DSA_SIGNATURE_LEN];
|
|
+ SECItem sig = {siBuffer, sigBuf, sizeof(sigBuf)};
|
|
+ /* can't use the default because we need to generate
|
|
+ * deterministic signatures */
|
|
+ CK_SIGN_ADDITIONAL_CONTEXT sig_context =
|
|
+ { CKH_DETERMINISTIC_REQUIRED, NULL, 0 };
|
|
+ SECItem sig_params={siBuffer, (unsigned char *)&sig_context,
|
|
+ sizeof(sig_context)};
|
|
+ PK11SymKey *Ks = NULL;
|
|
+ SECStatus rv;
|
|
+
|
|
+ sig_context.hedgeVariant = CKH_DETERMINISTIC_REQUIRED;
|
|
+ sig_context.pContext = NULL;
|
|
+ sig_context.ulContextLen = 0;
|
|
+
|
|
+ rv = PK11_SignWithMechanism(svrPrivKey, mechanism, &sig_params,
|
|
+ &sig, &msg);
|
|
+ if (rv != SECSuccess) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ Ks = PK11_RawPBEKeyGen(svrPrivKey->pkcs11Slot, masterWrapMech, NULL,
|
|
+ &sig, PR_FALSE, pwArg);
|
|
+ /* sigBuf became a CSP when we turned it into a password for the
|
|
+ * PBE */
|
|
+ PORT_SafeZero(sigBuf, sizeof(sigBuf));
|
|
+
|
|
+ if (Ks == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+ return Ks;
|
|
+}
|
|
+
|
|
/* Each process sharing the server session ID cache has its own array of SymKey
|
|
* pointers for the symmetric wrapping keys that are used to wrap the master
|
|
* secrets. There is one key for each authentication type. These Symkeys
|
|
* correspond to the wrapped SymKeys kept in the server session cache.
|
|
*/
|
|
const SSLAuthType ssl_wrap_key_auth_type[SSL_NUM_WRAP_KEYS] = {
|
|
ssl_auth_rsa_decrypt,
|
|
ssl_auth_rsa_sign,
|
|
ssl_auth_rsa_pss,
|
|
ssl_auth_ecdsa,
|
|
ssl_auth_ecdh_rsa,
|
|
- ssl_auth_ecdh_ecdsa
|
|
+ ssl_auth_ecdh_ecdsa,
|
|
+ ssl_auth_mldsa44,
|
|
+ ssl_auth_mldsa65,
|
|
+ ssl_auth_mldsa87
|
|
};
|
|
|
|
static SECStatus
|
|
ssl_FindIndexByWrapKey(const sslServerCert *serverCert, unsigned int *wrapKeyIndex)
|
|
{
|
|
unsigned int i;
|
|
for (i = 0; i < SSL_NUM_WRAP_KEYS; ++i) {
|
|
if (SSL_CERT_IS(serverCert, ssl_wrap_key_auth_type[i])) {
|
|
@@ -5958,29 +6119,46 @@ ssl_UnwrapSymWrappingKey(
|
|
|
|
wrappedKey.len = ecWrapped->wrappedKeyLen;
|
|
wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen +
|
|
ecWrapped->pubValueLen;
|
|
|
|
/* Derive Ks using ECDH */
|
|
Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL,
|
|
NULL, CKM_ECDH1_DERIVE, masterWrapMech,
|
|
- CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
|
|
+ CKA_DERIVE, 0, CKD_NULL, NULL, pwArg);
|
|
if (Ks == NULL) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Use Ks to unwrap the wrapping key */
|
|
unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL,
|
|
&wrappedKey, masterWrapMech,
|
|
CKA_UNWRAP, 0);
|
|
PK11_FreeSymKey(Ks);
|
|
|
|
break;
|
|
-
|
|
+ case ssl_auth_mldsa44:
|
|
+ case ssl_auth_mldsa65:
|
|
+ case ssl_auth_mldsa87:
|
|
+ /* Signature only algorithms can use a trick of signing a
|
|
+ * constant with the private key and using that constant
|
|
+ * as the password for a PBE. This only works if the
|
|
+ * signature is deterministic */
|
|
+ Ks = ssl_getSigKs(svrPrivKey, CKM_ML_DSA, masterWrapMech, pwArg);
|
|
+ if (Ks == NULL) {
|
|
+ goto loser;
|
|
+ }
|
|
+ /* Use Ks to unwrap the wrapping key */
|
|
+ unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL,
|
|
+ &wrappedKey, masterWrapMech,
|
|
+ CKA_UNWRAP, 0);
|
|
+ PK11_FreeSymKey(Ks);
|
|
+ break;
|
|
+ break;
|
|
default:
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
goto loser;
|
|
}
|
|
loser:
|
|
return unwrappedWrappingKey;
|
|
}
|
|
@@ -6244,16 +6422,33 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|
if (privWrapKey)
|
|
SECKEY_DestroyPrivateKey(privWrapKey);
|
|
if (pubWrapKey)
|
|
SECKEY_DestroyPublicKey(pubWrapKey);
|
|
if (Ks)
|
|
PK11_FreeSymKey(Ks);
|
|
asymWrapMechanism = masterWrapMech;
|
|
break;
|
|
+ case ssl_auth_mldsa44:
|
|
+ case ssl_auth_mldsa65:
|
|
+ case ssl_auth_mldsa87:
|
|
+ /* Signature only algorithms can use a trick of signing a
|
|
+ * constant with the private key and using that constant
|
|
+ * as the password for a PBE. This only works if the
|
|
+ * signature is deterministic */
|
|
+ Ks = ssl_getSigKs(svrPrivKey, CKM_ML_DSA, masterWrapMech, pwArg);
|
|
+ if (Ks == NULL) {
|
|
+ goto loser;
|
|
+ }
|
|
+ /* Use Ks to unwrap the wrapping key */
|
|
+ rv = PK11_WrapSymKey(masterWrapMech, NULL,Ks,
|
|
+ unwrappedWrappingKey, &wrappedKey);
|
|
+ PK11_FreeSymKey(Ks);
|
|
+ asymWrapMechanism = masterWrapMech;
|
|
+ break;
|
|
|
|
default:
|
|
rv = SECFailure;
|
|
break;
|
|
}
|
|
|
|
if (rv != SECSuccess) {
|
|
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
|
@@ -10334,23 +10529,25 @@ ssl3_SendServerKeyExchange(sslSocket *ss
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
break;
|
|
}
|
|
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
-ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
|
- PRBool grease, sslBuffer *buf)
|
|
+ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion,
|
|
+ PRUint16 maxVersion, PRBool forCert, PRBool grease,
|
|
+ sslBuffer *buf)
|
|
{
|
|
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
|
unsigned int filteredCount = 0;
|
|
|
|
- SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, PR_FALSE, forCert,
|
|
+ SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, maxVersion,
|
|
+ PR_FALSE, forCert,
|
|
PR_ARRAY_SIZE(filtered),
|
|
filtered, &filteredCount);
|
|
if (rv != SECSuccess) {
|
|
return SECFailure;
|
|
}
|
|
return ssl3_EncodeFilteredSigAlgs(ss, filtered, filteredCount, grease, buf);
|
|
}
|
|
|
|
@@ -10417,17 +10614,18 @@ ssl3_EncodeFilteredSigAlgs(const sslSock
|
|
* that include PKCS#1. Hence, forCert is used to enable advertising
|
|
* PKCS#1 support. Note that we include these in signature_algorithms
|
|
* because we don't yet support signature_algorithms_cert. TLS 1.3
|
|
* requires that PKCS#1 schemes are placed last in the list if they
|
|
* are present. This sorting can be removed once we support
|
|
* signature_algorithms_cert.
|
|
*/
|
|
SECStatus
|
|
-ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
|
|
+ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRUint16 maxVersion,
|
|
+ PRBool disableRsae,
|
|
PRBool forCert,
|
|
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
|
unsigned int *numFilteredSchemes)
|
|
{
|
|
PORT_Assert(filteredSchemes);
|
|
PORT_Assert(numFilteredSchemes);
|
|
PORT_Assert(maxSchemes >= ss->ssl3.signatureSchemeCount);
|
|
if (maxSchemes < ss->ssl3.signatureSchemeCount) {
|
|
@@ -10435,31 +10633,31 @@ ssl3_FilterSigAlgs(const sslSocket *ss,
|
|
}
|
|
|
|
*numFilteredSchemes = 0;
|
|
PRBool allowUnsortedPkcs1 = forCert && minVersion < SSL_LIBRARY_VERSION_TLS_1_3;
|
|
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
|
continue;
|
|
}
|
|
- if (ssl_SignatureSchemeAccepted(minVersion,
|
|
+ if (ssl_SignatureSchemeAccepted(minVersion, maxVersion,
|
|
ss->ssl3.signatureSchemes[i],
|
|
allowUnsortedPkcs1)) {
|
|
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
|
}
|
|
}
|
|
if (forCert && !allowUnsortedPkcs1) {
|
|
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
|
continue;
|
|
}
|
|
- if (!ssl_SignatureSchemeAccepted(minVersion,
|
|
+ if (!ssl_SignatureSchemeAccepted(minVersion, maxVersion,
|
|
ss->ssl3.signatureSchemes[i],
|
|
PR_FALSE) &&
|
|
- ssl_SignatureSchemeAccepted(minVersion,
|
|
+ ssl_SignatureSchemeAccepted(minVersion, maxVersion,
|
|
ss->ssl3.signatureSchemes[i],
|
|
PR_TRUE)) {
|
|
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
|
}
|
|
}
|
|
}
|
|
return SECSuccess;
|
|
}
|
|
@@ -10492,17 +10690,18 @@ ssl3_SendCertificateRequest(sslSocket *s
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
certTypes = certificate_types;
|
|
certTypesLength = sizeof certificate_types;
|
|
|
|
length = 1 + certTypesLength + 2 + calen;
|
|
if (isTLS12) {
|
|
- rv = ssl3_EncodeSigAlgs(ss, ss->version, PR_TRUE /* forCert */,
|
|
+ rv = ssl3_EncodeSigAlgs(ss, ss->version, ss->version,
|
|
+ PR_TRUE /* forCert */,
|
|
PR_FALSE /* GREASE */, &sigAlgsBuf);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
length += SSL_BUFFER_LEN(&sigAlgsBuf);
|
|
}
|
|
|
|
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request, length);
|
|
@@ -11196,21 +11395,19 @@ get_fake_cert(SECItem *pCertItem, int *p
|
|
numBytes = PR_Read(cf, pCertItem->data, info.size);
|
|
}
|
|
PR_Close(cf);
|
|
if (numBytes != info.size) {
|
|
SECITEM_FreeItem(pCertItem, PR_FALSE);
|
|
PORT_SetError(SEC_ERROR_IO);
|
|
goto loser;
|
|
}
|
|
- fprintf(stderr, "using %s\n", cfn);
|
|
return SECSuccess;
|
|
|
|
loser:
|
|
- fprintf(stderr, "failed to use %s\n", cfn);
|
|
*pIndex = -1;
|
|
return SECFailure;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Used by both client and server.
|
|
* Called from HandleServerHelloDone and from SendServerHelloSequence.
|
|
@@ -11698,16 +11895,21 @@ ssl_SetAuthKeyBits(sslSocket *ss, const
|
|
if (rv == SECSuccess && optval > 0) {
|
|
minKey = (PRUint32)optval;
|
|
} else {
|
|
/* Don't check EC strength here on the understanding that we
|
|
* only support curves we like. */
|
|
minKey = ss->sec.authKeyBits;
|
|
}
|
|
break;
|
|
+ case mldsaKey:
|
|
+ /* ML DSA has fixed sizes and are handled by separate oids
|
|
+ * for each key */
|
|
+ minKey = ss->sec.authKeyBits;
|
|
+ break;
|
|
|
|
default:
|
|
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
|
|
return SECFailure;
|
|
}
|
|
|
|
/* Too small: not good enough. Send a fatal alert. */
|
|
if (ss->sec.authKeyBits < minKey) {
|
|
@@ -14059,16 +14261,17 @@ SSL_SignatureSchemePrefSet(PRFileDesc *f
|
|
SSL_GETPID(), fd, schemes[i]));
|
|
continue;
|
|
}
|
|
|
|
ss->ssl3.signatureSchemes[ss->ssl3.signatureSchemeCount++] = schemes[i];
|
|
}
|
|
|
|
if (ss->ssl3.signatureSchemeCount == 0) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
|
|
return SECFailure;
|
|
}
|
|
return SECSuccess;
|
|
}
|
|
|
|
SECStatus
|
|
SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
|
|
diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c
|
|
--- a/lib/ssl/ssl3exthandle.c
|
|
+++ b/lib/ssl/ssl3exthandle.c
|
|
@@ -1650,23 +1650,27 @@ SECStatus
|
|
ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|
sslBuffer *buf, PRBool *added)
|
|
{
|
|
if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_2) {
|
|
return SECSuccess;
|
|
}
|
|
|
|
PRUint16 minVersion;
|
|
+ PRUint16 maxVersion;
|
|
if (ss->sec.isServer) {
|
|
minVersion = ss->version; /* CertificateRequest */
|
|
+ maxVersion = ss->version;
|
|
} else {
|
|
minVersion = ss->vrange.min; /* ClientHello */
|
|
+ maxVersion = ss->vrange.max; /* ClientHello */
|
|
}
|
|
|
|
- SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, PR_TRUE /* forCert */,
|
|
+ SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, maxVersion,
|
|
+ PR_TRUE /* forCert */,
|
|
ss->opt.enableGrease, buf);
|
|
if (rv != SECSuccess) {
|
|
return SECFailure;
|
|
}
|
|
|
|
*added = PR_TRUE;
|
|
return SECSuccess;
|
|
}
|
|
diff --git a/lib/ssl/sslcert.c b/lib/ssl/sslcert.c
|
|
--- a/lib/ssl/sslcert.c
|
|
+++ b/lib/ssl/sslcert.c
|
|
@@ -8,16 +8,17 @@
|
|
|
|
#include "ssl.h"
|
|
#include "sslimpl.h"
|
|
#include "secoid.h" /* for SECOID_GetAlgorithmTag */
|
|
#include "pk11func.h" /* for PK11_ReferenceSlot */
|
|
#include "nss.h" /* for NSS_RegisterShutdown */
|
|
#include "prinit.h" /* for PR_CallOnceWithArg */
|
|
#include "tls13subcerts.h" /* for tls13_ReadDelegatedCredential */
|
|
+#include "secmodti.h" /* for private OID defines, don't upstream */
|
|
|
|
/* This global item is used only in servers. It is is initialized by
|
|
* SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
|
|
*/
|
|
static struct {
|
|
PRCallOnceType setup;
|
|
CERTDistNames *names;
|
|
} ssl_server_ca_list;
|
|
@@ -565,16 +566,34 @@ ssl_GetCertificateAuthTypes(CERTCertific
|
|
authTypes |= 1 << ssl_auth_ecdsa;
|
|
}
|
|
/* Again, bad form to have dual usage and we don't prevent it. */
|
|
if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
|
|
authTypes |= 1 << ssl_GetEcdhAuthType(cert);
|
|
}
|
|
break;
|
|
|
|
+ case SEC_OID_ML_DSA_44:
|
|
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
|
+ authTypes |= 1 << ssl_auth_mldsa44;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SEC_OID_ML_DSA_65:
|
|
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
|
+ authTypes |= 1 << ssl_auth_mldsa65;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SEC_OID_ML_DSA_87:
|
|
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
|
+ authTypes |= 1 << ssl_auth_mldsa87;
|
|
+ }
|
|
+ break;
|
|
+
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Check that we successfully picked an authType */
|
|
if (targetAuthType != ssl_auth_null) {
|
|
authTypes &= 1 << targetAuthType;
|
|
}
|
|
@@ -726,16 +745,25 @@ ssl_CertSuitableForAuthType(CERTCertific
|
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
|
mask |= 1 << ssl_auth_dsa;
|
|
break;
|
|
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
|
mask |= 1 << ssl_auth_ecdsa;
|
|
mask |= 1 << ssl_auth_ecdh_rsa;
|
|
mask |= 1 << ssl_auth_ecdh_ecdsa;
|
|
break;
|
|
+ case SEC_OID_ML_DSA_44:
|
|
+ mask |= 1 << ssl_auth_mldsa44;
|
|
+ break;
|
|
+ case SEC_OID_ML_DSA_65:
|
|
+ mask |= 1 << ssl_auth_mldsa65;
|
|
+ break;
|
|
+ case SEC_OID_ML_DSA_87:
|
|
+ mask |= 1 << ssl_auth_mldsa87;
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
PORT_Assert(authTypes);
|
|
/* Simply test that no inappropriate auth types are set. */
|
|
return (authTypes & ~mask) == 0;
|
|
}
|
|
|
|
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
|
|
--- a/lib/ssl/sslimpl.h
|
|
+++ b/lib/ssl/sslimpl.h
|
|
@@ -41,16 +41,17 @@ typedef struct sslNamedGroupDefStr sslNa
|
|
typedef struct sslEchConfigStr sslEchConfig;
|
|
typedef struct sslEchConfigContentsStr sslEchConfigContents;
|
|
typedef struct sslEchCookieDataStr sslEchCookieData;
|
|
typedef struct sslEchXtnStateStr sslEchXtnState;
|
|
typedef struct sslPskStr sslPsk;
|
|
typedef struct sslDelegatedCredentialStr sslDelegatedCredential;
|
|
typedef struct sslEphemeralKeyPairStr sslEphemeralKeyPair;
|
|
typedef struct TLS13KeyShareEntryStr TLS13KeyShareEntry;
|
|
+typedef struct tlsSignOrVerifyContextStr tlsSignOrVerifyContext;
|
|
|
|
#include "sslencode.h"
|
|
#include "sslexp.h"
|
|
#include "ssl3ext.h"
|
|
#include "sslspec.h"
|
|
|
|
#if defined(DEBUG) || defined(TRACE)
|
|
#ifdef __cplusplus
|
|
@@ -108,17 +109,17 @@ typedef enum { SSLAppOpRead = 0,
|
|
|
|
#define SSL_MIN_CHALLENGE_BYTES 16
|
|
#define SSL_MAX_CHALLENGE_BYTES 32
|
|
|
|
#define SSL3_MASTER_SECRET_LENGTH 48
|
|
|
|
/* number of wrap mechanisms potentially used to wrap master secrets. */
|
|
#define SSL_NUM_WRAP_MECHS 15
|
|
-#define SSL_NUM_WRAP_KEYS 6
|
|
+#define SSL_NUM_WRAP_KEYS 9
|
|
|
|
/* This makes the cert cache entry exactly 4k. */
|
|
#define SSL_MAX_CACHED_CERT_LEN 4060
|
|
|
|
#ifndef BPB
|
|
#define BPB 8 /* Bits Per Byte */
|
|
#endif
|
|
|
|
@@ -1689,30 +1690,39 @@ extern SECStatus ssl_CheckSignatureSchem
|
|
sslSocket *ss, SSLSignatureScheme scheme, CERTSubjectPublicKeyInfo *spki);
|
|
extern SECStatus ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
|
|
SSLSignatureScheme **schemesOut,
|
|
unsigned int *numSchemesOut,
|
|
unsigned char **b,
|
|
unsigned int *len);
|
|
extern SECStatus ssl_ConsumeSignatureScheme(
|
|
sslSocket *ss, PRUint8 **b, PRUint32 *length, SSLSignatureScheme *out);
|
|
-extern SECStatus ssl3_SignHashesWithPrivKey(SSL3Hashes *hash,
|
|
- SECKEYPrivateKey *key,
|
|
- SSLSignatureScheme scheme,
|
|
- PRBool isTls,
|
|
- SECItem *buf);
|
|
extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash,
|
|
SECKEYPrivateKey *key, SECItem *buf);
|
|
-extern SECStatus ssl_VerifySignedHashesWithPubKey(sslSocket *ss,
|
|
- SECKEYPublicKey *spki,
|
|
- SSLSignatureScheme scheme,
|
|
- SSL3Hashes *hash,
|
|
- SECItem *buf);
|
|
extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme,
|
|
SSL3Hashes *hash, SECItem *buf);
|
|
+/* new signaure algorithms don't really have a 'sign hashes' interface,
|
|
+ * TLS13 now supports proper signing, where, if we are signing hashes, we
|
|
+ * will sign them with a proper hash and signed signature. Provide
|
|
+ * an API for those places in tls 13 where we need to sign. This leverages
|
|
+ * the work in secsign and secvfy, so we don't need to add a lot of
|
|
+ * algorithm specific code. Once the sign/verify interfaces work, we can
|
|
+ * just add the oid in tls13con.c and the ssl_sig_xxxx value and we are
|
|
+ * good to go */
|
|
+extern tlsSignOrVerifyContext * tls_SignOrVerifyGetNewContext(
|
|
+ SECKEYPrivateKey *privKey,
|
|
+ SECKEYPublicKey *pubKey,
|
|
+ SSLSignatureScheme scheme, PRBool sign,
|
|
+ SECItem *signature, void *pwArg);
|
|
+SECStatus tls_SignOrVerifyUpdate(tlsSignOrVerifyContext *ctx,
|
|
+ const unsigned char *buf, int len);
|
|
+SECStatus tls_SignOrVerifyEnd(tlsSignOrVerifyContext *ctx, SECItem *sig);
|
|
+void tls_DestroySignOrVerifyContext(tlsSignOrVerifyContext *ctx);
|
|
+
|
|
+
|
|
extern SECStatus ssl3_CacheWrappedSecret(sslSocket *ss, sslSessionID *sid,
|
|
PK11SymKey *secret);
|
|
extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData);
|
|
|
|
/* Hello Extension related routines. */
|
|
extern void ssl3_SetSIDSessionTicket(sslSessionID *sid,
|
|
/*in/out*/ NewSessionTicket *session_ticket);
|
|
SECStatus ssl3_EncodeSessionTicket(sslSocket *ss,
|
|
@@ -1789,22 +1799,24 @@ SECStatus ssl3_HandleNoCertificate(sslSo
|
|
SECStatus ssl3_SendEmptyCertificate(sslSocket *ss);
|
|
void ssl3_CleanupPeerCerts(sslSocket *ss);
|
|
SECStatus ssl3_SendCertificateStatus(sslSocket *ss);
|
|
SECStatus ssl_SetAuthKeyBits(sslSocket *ss, const SECKEYPublicKey *pubKey);
|
|
SECStatus ssl3_HandleServerSpki(sslSocket *ss);
|
|
SECStatus ssl3_AuthCertificate(sslSocket *ss);
|
|
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
|
|
PRUint32 length);
|
|
-SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
|
+SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion,
|
|
+ PRUint16 maxVersion, PRBool forCert,
|
|
PRBool grease, sslBuffer *buf);
|
|
SECStatus ssl3_EncodeFilteredSigAlgs(const sslSocket *ss,
|
|
const SSLSignatureScheme *schemes,
|
|
PRUint32 numSchemes, PRBool grease, sslBuffer *buf);
|
|
-SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae, PRBool forCert,
|
|
+SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion,
|
|
+ PRUint16 maxVersion, PRBool disableRsae, PRBool forCert,
|
|
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
|
unsigned int *numFilteredSchemes);
|
|
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
|
|
unsigned int *calenp,
|
|
const SECItem **namesp,
|
|
unsigned int *nnamesp);
|
|
SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b,
|
|
PRUint32 *length, CERTDistNames *ca_list);
|
|
@@ -1854,26 +1866,28 @@ SECStatus ssl_PickSignatureScheme(sslSoc
|
|
SSLSignatureScheme *schemPtr);
|
|
SECStatus ssl_PickClientSignatureScheme(sslSocket *ss,
|
|
CERTCertificate *clientCertificate,
|
|
SECKEYPrivateKey *privKey,
|
|
const SSLSignatureScheme *schemes,
|
|
unsigned int numSchemes,
|
|
SSLSignatureScheme *schemePtr);
|
|
SECOidTag ssl3_HashTypeToOID(SSLHashType hashType);
|
|
-SECOidTag ssl3_AuthTypeToOID(SSLAuthType hashType);
|
|
+SECOidTag ssl3_AuthTypeToOID(SSLAuthType authType);
|
|
SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme);
|
|
SSLAuthType ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme);
|
|
|
|
SECStatus ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes);
|
|
SECStatus ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
|
|
SSLContentType contentType, sslBuffer *wrBuf,
|
|
PRBool *needsLength);
|
|
PRBool ssl_SignatureSchemeValid(SSLSignatureScheme scheme, SECOidTag spkiOid,
|
|
PRBool isTls13);
|
|
+SSLSignatureScheme ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag);
|
|
+
|
|
|
|
/* Pull in DTLS functions */
|
|
#include "dtlscon.h"
|
|
|
|
/* Pull in TLS 1.3 functions */
|
|
#include "tls13con.h"
|
|
#include "dtls13con.h"
|
|
|
|
diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
|
|
--- a/lib/ssl/sslt.h
|
|
+++ b/lib/ssl/sslt.h
|
|
@@ -116,17 +116,20 @@ typedef enum {
|
|
/* ssl_hash_none is used internally to mean the pre-1.2 combination of MD5
|
|
* and SHA1. The other values are only used in TLS 1.2. */
|
|
ssl_hash_none = 0,
|
|
ssl_hash_md5 = 1,
|
|
ssl_hash_sha1 = 2,
|
|
ssl_hash_sha224 = 3,
|
|
ssl_hash_sha256 = 4,
|
|
ssl_hash_sha384 = 5,
|
|
- ssl_hash_sha512 = 6
|
|
+ ssl_hash_sha512 = 6,
|
|
+ ssl_hash_mldsa44 = 7, /* these make sure mldsa works, */
|
|
+ ssl_hash_mldsa65 = 8, /* but only for tls 1.3, attempts */
|
|
+ ssl_hash_mldsa87 = 9, /* to hash will these will fail */
|
|
} SSLHashType;
|
|
|
|
/* Deprecated */
|
|
typedef struct SSLSignatureAndHashAlgStr {
|
|
SSLHashType hashAlg;
|
|
SSLSignType sigAlg;
|
|
} SSLSignatureAndHashAlg;
|
|
|
|
@@ -151,16 +154,20 @@ typedef enum {
|
|
ssl_sig_rsa_pss_pss_sha512 = 0x080b,
|
|
|
|
ssl_sig_dsa_sha1 = 0x0202,
|
|
ssl_sig_dsa_sha256 = 0x0402,
|
|
ssl_sig_dsa_sha384 = 0x0502,
|
|
ssl_sig_dsa_sha512 = 0x0602,
|
|
ssl_sig_ecdsa_sha1 = 0x0203,
|
|
|
|
+ ssl_sig_mldsa44 = 0x0904,
|
|
+ ssl_sig_mldsa65 = 0x0905,
|
|
+ ssl_sig_mldsa87 = 0x0906,
|
|
+
|
|
/* The following value (which can't be used in the protocol), represents
|
|
* the RSA signature using SHA-1 and MD5 that is used in TLS 1.0 and 1.1.
|
|
* This is reported as a signature scheme when TLS 1.0 or 1.1 is used.
|
|
* This should not be passed to SSL_SignatureSchemePrefSet(); this
|
|
* signature scheme is always used and cannot be disabled. */
|
|
ssl_sig_rsa_pkcs1_sha1md5 = 0x10101,
|
|
} SSLSignatureScheme;
|
|
|
|
@@ -180,16 +187,19 @@ typedef enum {
|
|
ssl_auth_kea = 3, /* unused */
|
|
ssl_auth_ecdsa = 4,
|
|
ssl_auth_ecdh_rsa = 5, /* ECDH cert with an RSA signature. */
|
|
ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature. */
|
|
ssl_auth_rsa_sign = 7, /* RSA signing with an rsaEncryption key. */
|
|
ssl_auth_rsa_pss = 8, /* RSA signing with a PSS key. */
|
|
ssl_auth_psk = 9,
|
|
ssl_auth_tls13_any = 10,
|
|
+ ssl_auth_mldsa44 = 11, /* use separate auth for each paramset */
|
|
+ ssl_auth_mldsa65 = 12, /* so we can properly identify the certs */
|
|
+ ssl_auth_mldsa87 = 13,
|
|
ssl_auth_size /* number of authentication types */
|
|
} SSLAuthType;
|
|
|
|
typedef enum {
|
|
ssl_psk_none = 0,
|
|
ssl_psk_resume = 1,
|
|
ssl_psk_external = 2,
|
|
} SSLPskType;
|
|
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
|
|
--- a/lib/ssl/tls13con.c
|
|
+++ b/lib/ssl/tls13con.c
|
|
@@ -10,16 +10,19 @@
|
|
#include "stdarg.h"
|
|
#include "cert.h"
|
|
#include "ssl.h"
|
|
#include "keyhi.h"
|
|
#include "pk11func.h"
|
|
#include "prerr.h"
|
|
#include "secitem.h"
|
|
#include "secmod.h"
|
|
+#include "secmodti.h" /* don't upstream, to get private SEC_OID_ defines */
|
|
+#include "cryptohi.h"
|
|
+#include "sechash.h"
|
|
#include "sslimpl.h"
|
|
#include "sslproto.h"
|
|
#include "sslerr.h"
|
|
#include "ssl3exthandle.h"
|
|
#include "tls13hkdf.h"
|
|
#include "tls13con.h"
|
|
#include "tls13err.h"
|
|
#include "tls13ech.h"
|
|
@@ -4494,76 +4497,368 @@ tls13_HandleCertificate(sslSocket *ss, P
|
|
|
|
first = PR_FALSE;
|
|
}
|
|
SECKEY_UpdateCertPQG(ss->sec.peerCert);
|
|
|
|
return ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
|
|
}
|
|
|
|
+/* this should be in cryptohi, but we need can't create a new API
|
|
+ * for it which doesn't try to parse old parameters and select things
|
|
+ * based on the privkey stuff */
|
|
+static
|
|
+SECItem *
|
|
+tls_encodeRSAParams(PLArenaPool *arena, SECOidTag hashAlgTag)
|
|
+{
|
|
+ SECKEYRSAPSSParams pssParams;
|
|
+ SECStatus rv;
|
|
+ int saltLen;
|
|
+ SECItem *hashAlgItem = NULL;
|
|
+ SECItem *saltItem = NULL;
|
|
+
|
|
+ PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
|
+
|
|
+ /* RSA PSS let's us default SHA1, but we know this can only be called
|
|
+ * for TLS 1.3 and greater, and there isn't any SHA-1 in TLS 1.3, so
|
|
+ * we can skip those checks */
|
|
+ pssParams.hashAlg = PORT_ArenaZNew(arena, SECAlgorithmID);
|
|
+ if (!pssParams.hashAlg) {
|
|
+ return NULL;
|
|
+ }
|
|
+ rv = SECOID_SetAlgorithmID(arena, pssParams.hashAlg, hashAlgTag, NULL);
|
|
+ if (rv != SECSuccess) {
|
|
+ return NULL;
|
|
+ }
|
|
+ hashAlgItem = SEC_ASN1EncodeItem(arena, NULL, pssParams.hashAlg,
|
|
+ SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
|
|
+ if (!hashAlgItem) {
|
|
+ return NULL;
|
|
+ }
|
|
+ pssParams.maskAlg = PORT_ArenaZNew(arena, SECAlgorithmID);
|
|
+ if (!pssParams.maskAlg) {
|
|
+ return NULL;
|
|
+ }
|
|
+ rv = SECOID_SetAlgorithmID(arena, pssParams.maskAlg,
|
|
+ SEC_OID_PKCS1_MGF1, hashAlgItem);
|
|
+ if (rv != SECSuccess) {
|
|
+ return NULL;
|
|
+ }
|
|
+ saltLen = HASH_ResultLenByOidTag(hashAlgTag);
|
|
+ if (saltLen == 0) {
|
|
+ return NULL;
|
|
+ }
|
|
+ saltItem = SEC_ASN1EncodeInteger(arena, &pssParams.saltLength, saltLen);
|
|
+ if (!saltItem) {
|
|
+ return NULL;
|
|
+ }
|
|
+ return SEC_ASN1EncodeItem(arena, NULL, &pssParams, SECKEY_RSAPSSParamsTemplate);
|
|
+}
|
|
+
|
|
+/* we put this here because it only affects TLS 1.3, TLS 1.2 and earlier
|
|
+ * use the old sign hashes interface. TLS 1.3 is friendly to algorthims
|
|
+ * that don't have a signed hashes interface */
|
|
+/* we generate an algorithm ID rather than just use an OID to support RSAPSS.
|
|
+ * It's generated completely from the scheme, without the key */
|
|
+SECAlgorithmID *
|
|
+tls_GetSignatureAlgorithmId(PLArenaPool *arena, SSLSignatureScheme scheme)
|
|
+{
|
|
+ SECAlgorithmID *newAlgID = PORT_ArenaZNew(arena, SECAlgorithmID);
|
|
+ SECOidTag algTag = SEC_OID_UNKNOWN;
|
|
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
|
|
+ SECItem *params = NULL;
|
|
+ SECStatus rv;
|
|
+
|
|
+ switch (scheme) {
|
|
+ /* do rsa PSS first because it needs to set the params
|
|
+ * for the algTag the difference between rsa_pss_rsae and
|
|
+ * rsa_pss_pss is in the selection an validation of the cert
|
|
+ * At this stage, the signatures are the same, so for our
|
|
+ * purposed they are equivalent */
|
|
+ case ssl_sig_rsa_pss_rsae_sha256:
|
|
+ case ssl_sig_rsa_pss_pss_sha256:
|
|
+ hashAlgTag = SEC_OID_SHA256;
|
|
+ goto rsa_pss_next;
|
|
+ case ssl_sig_rsa_pss_rsae_sha384:
|
|
+ case ssl_sig_rsa_pss_pss_sha384:
|
|
+ hashAlgTag = SEC_OID_SHA384;
|
|
+ goto rsa_pss_next;
|
|
+ case ssl_sig_rsa_pss_rsae_sha512:
|
|
+ case ssl_sig_rsa_pss_pss_sha512:
|
|
+ hashAlgTag = SEC_OID_SHA512;
|
|
+rsa_pss_next:
|
|
+ params = tls_encodeRSAParams(arena, hashAlgTag);
|
|
+ if (params == NULL) {
|
|
+ break;
|
|
+ }
|
|
+ algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
|
|
+ break;
|
|
+ /* the curve comes from the key and should have already been
|
|
+ * enforced at a different level */
|
|
+ case ssl_sig_ecdsa_secp256r1_sha256:
|
|
+ algTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
|
|
+ break;
|
|
+ case ssl_sig_ecdsa_secp384r1_sha384:
|
|
+ algTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
|
|
+ break;
|
|
+ case ssl_sig_ecdsa_secp521r1_sha512:
|
|
+ algTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
|
|
+ break;
|
|
+ case ssl_sig_mldsa44:
|
|
+ algTag = SEC_OID_ML_DSA_44;
|
|
+ break;
|
|
+ case ssl_sig_mldsa65:
|
|
+ algTag = SEC_OID_ML_DSA_65;
|
|
+ break;
|
|
+ case ssl_sig_mldsa87:
|
|
+ algTag = SEC_OID_ML_DSA_87;
|
|
+ break;
|
|
+
|
|
+ /* the following is unsupported in tls 1.3 and greater, just break.
|
|
+ * We include them here explicitly so we get the compiler warning about
|
|
+ * missing enums in the switch statement. default would be a break anyway.
|
|
+ * That way we'll know to update this table when new algorithsm are
|
|
+ * added */
|
|
+
|
|
+ /* as of now sig ed is not supported in NSS. That could change, and this
|
|
+ * is part the code that would pick up the change (need OIDS for the
|
|
+ * hash variants of these signature, and then add them here) */
|
|
+ case ssl_sig_ed25519:
|
|
+ case ssl_sig_ed448:
|
|
+
|
|
+ /* sha1 hashes in sigs are explicitly disallowed int TLS 1.3 or greater */
|
|
+ case ssl_sig_ecdsa_sha1:
|
|
+
|
|
+ /* rsa pkcs1 sigs are explicitly disallowed in TLS 1.3 and greater */
|
|
+ case ssl_sig_rsa_pkcs1_sha1:
|
|
+ case ssl_sig_rsa_pkcs1_sha256:
|
|
+ case ssl_sig_rsa_pkcs1_sha384:
|
|
+ case ssl_sig_rsa_pkcs1_sha512:
|
|
+
|
|
+ /* dsa sigs are explicitly disallowed in TLS 1.3 and greater */
|
|
+ case ssl_sig_dsa_sha1:
|
|
+ case ssl_sig_dsa_sha256:
|
|
+ case ssl_sig_dsa_sha384:
|
|
+ case ssl_sig_dsa_sha512:
|
|
+
|
|
+ /* special sig variants that aren't supported in TLS 1.3 or greater */
|
|
+ case ssl_sig_rsa_pkcs1_sha1md5:
|
|
+ case ssl_sig_none:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* the earlier code should have made sure none of the unsupported
|
|
+ * algorithms were accepted */
|
|
+ PORT_Assert(algTag != SEC_OID_UNKNOWN);
|
|
+ if (algTag == SEC_OID_UNKNOWN) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ rv = SECOID_SetAlgorithmID(arena, newAlgID, algTag, params);
|
|
+ if (rv != SECSuccess) {
|
|
+ return NULL;
|
|
+ }
|
|
+ return newAlgID;
|
|
+}
|
|
+
|
|
+struct tlsSignOrVerifyContextStr {
|
|
+ PRBool sign;
|
|
+ union {
|
|
+ SGNContext *sig;
|
|
+ VFYContext *vfy;
|
|
+ } u;
|
|
+};
|
|
+
|
|
+tlsSignOrVerifyContext *
|
|
+tls_SignOrVerifyGetNewContext(SECKEYPrivateKey *privKey,
|
|
+ SECKEYPublicKey *pubKey,
|
|
+ SSLSignatureScheme scheme, PRBool sign,
|
|
+ SECItem *signature, void *pwArg)
|
|
+{
|
|
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
|
+ SECAlgorithmID *sigAlgID = NULL;
|
|
+ tlsSignOrVerifyContext *newCtx = PORT_ZNew(tlsSignOrVerifyContext);
|
|
+ SECStatus rv;
|
|
+
|
|
+ if (!newCtx) {
|
|
+ goto loser;
|
|
+ }
|
|
+
|
|
+ if (!arena) {
|
|
+ goto loser;
|
|
+ }
|
|
+
|
|
+ if (sign) {
|
|
+ PORT_Assert(privKey);
|
|
+ } else {
|
|
+ PORT_Assert(pubKey);
|
|
+ }
|
|
+
|
|
+ if ((sign && !privKey) || (!sign && !pubKey)) {
|
|
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
+ goto loser;
|
|
+ }
|
|
+
|
|
+ newCtx->sign = sign;
|
|
+
|
|
+ sigAlgID = tls_GetSignatureAlgorithmId(arena, scheme);
|
|
+ if (sigAlgID == NULL) {
|
|
+ goto loser;
|
|
+ }
|
|
+ if (sign) {
|
|
+ newCtx->u.sig= SGN_NewContextWithAlgorithmID(sigAlgID, privKey);
|
|
+ if (!newCtx->u.sig) {
|
|
+ goto loser;
|
|
+ }
|
|
+ rv = SGN_Begin(newCtx->u.sig);
|
|
+ } else {
|
|
+ newCtx->u.vfy = VFY_CreateContextWithAlgorithmID(pubKey, signature,
|
|
+ sigAlgID, NULL, pwArg);
|
|
+ if (!newCtx->u.vfy) {
|
|
+ goto loser;
|
|
+ }
|
|
+ rv = VFY_Begin(newCtx->u.vfy);
|
|
+ }
|
|
+ if (rv != SECSuccess) {
|
|
+ goto loser;
|
|
+ }
|
|
+ PORT_FreeArena(arena, PR_FALSE);
|
|
+ return (newCtx);
|
|
+
|
|
+loser:
|
|
+ tls_DestroySignOrVerifyContext(newCtx);
|
|
+ if (arena) {
|
|
+ PORT_FreeArena(arena, PR_FALSE);
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+
|
|
+SECStatus
|
|
+tls_SignOrVerifyUpdate(tlsSignOrVerifyContext *ctx, const unsigned char *buf,
|
|
+ int len)
|
|
+{
|
|
+ SECStatus rv;
|
|
+ if (ctx->sign) {
|
|
+ rv = SGN_Update(ctx->u.sig, buf, len);
|
|
+ } else {
|
|
+ rv = VFY_Update(ctx->u.vfy, buf, len);
|
|
+ }
|
|
+ return rv;
|
|
+}
|
|
+
|
|
+SECStatus
|
|
+tls_SignOrVerifyEnd(tlsSignOrVerifyContext *ctx, SECItem *sig)
|
|
+{
|
|
+ SECStatus rv;
|
|
+ if (ctx->sign) {
|
|
+ rv = SGN_End(ctx->u.sig, sig);
|
|
+ } else {
|
|
+ /* sign is already set in the context */
|
|
+ rv = VFY_End(ctx->u.vfy);
|
|
+ }
|
|
+ return rv;
|
|
+}
|
|
+
|
|
+void
|
|
+tls_DestroySignOrVerifyContext(tlsSignOrVerifyContext *ctx)
|
|
+{
|
|
+ if (!ctx) {
|
|
+ return;
|
|
+ }
|
|
+ if (ctx->sign) {
|
|
+ if (ctx->u.sig) {
|
|
+ SGN_DestroyContext(ctx->u.sig, PR_TRUE);
|
|
+ }
|
|
+ } else {
|
|
+ if (ctx->u.vfy) {
|
|
+ VFY_DestroyContext(ctx->u.vfy, PR_TRUE);
|
|
+ }
|
|
+ }
|
|
+ PORT_Free(ctx);
|
|
+}
|
|
+
|
|
+
|
|
/* Add context to the hash functions as described in
|
|
[draft-ietf-tls-tls13; Section 4.9.1] */
|
|
SECStatus
|
|
-tls13_AddContextToHashes(sslSocket *ss, const SSL3Hashes *hashes,
|
|
- SSLHashType algorithm, PRBool sending,
|
|
- SSL3Hashes *tbsHash)
|
|
+tls13_SignOrVerifyHashWithContext(sslSocket *ss, const SSL3Hashes *hashes,
|
|
+ SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
|
|
+ SSLSignatureScheme scheme, PRBool sending,
|
|
+ SECItem *signature)
|
|
{
|
|
SECStatus rv = SECSuccess;
|
|
- PK11Context *ctx;
|
|
+ tlsSignOrVerifyContext *ctx = NULL;
|
|
+ void *pwArg = ss->pkcs11PinArg;
|
|
const unsigned char context_padding[] = {
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
|
|
};
|
|
|
|
const char *client_cert_verify_string = "TLS 1.3, client CertificateVerify";
|
|
const char *server_cert_verify_string = "TLS 1.3, server CertificateVerify";
|
|
const char *context_string = (sending ^ ss->sec.isServer) ? client_cert_verify_string
|
|
: server_cert_verify_string;
|
|
- unsigned int hashlength;
|
|
|
|
/* Double check that we are doing the same hash.*/
|
|
PORT_Assert(hashes->len == tls13_GetHashSize(ss));
|
|
-
|
|
- ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(algorithm));
|
|
- if (!ctx) {
|
|
- PORT_SetError(SEC_ERROR_NO_MEMORY);
|
|
- goto loser;
|
|
- }
|
|
-
|
|
- PORT_Assert(SECFailure);
|
|
- PORT_Assert(!SECSuccess);
|
|
+ if (hashes->len != tls13_GetHashSize(ss)) {
|
|
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
+ return SECFailure;
|
|
+ }
|
|
|
|
PRINT_BUF(50, (ss, "TLS 1.3 hash without context", hashes->u.raw, hashes->len));
|
|
PRINT_BUF(50, (ss, "Context string", context_string, strlen(context_string)));
|
|
- rv |= PK11_DigestBegin(ctx);
|
|
- rv |= PK11_DigestOp(ctx, context_padding, sizeof(context_padding));
|
|
- rv |= PK11_DigestOp(ctx, (unsigned char *)context_string,
|
|
- strlen(context_string) + 1); /* +1 includes the terminating 0 */
|
|
- rv |= PK11_DigestOp(ctx, hashes->u.raw, hashes->len);
|
|
- /* Update the hash in-place */
|
|
- rv |= PK11_DigestFinal(ctx, tbsHash->u.raw, &hashlength, sizeof(tbsHash->u.raw));
|
|
- PK11_DestroyContext(ctx, PR_TRUE);
|
|
- PRINT_BUF(50, (ss, "TLS 1.3 hash with context", tbsHash->u.raw, hashlength));
|
|
-
|
|
- tbsHash->len = hashlength;
|
|
- tbsHash->hashAlg = algorithm;
|
|
-
|
|
+
|
|
+ ctx = tls_SignOrVerifyGetNewContext(privKey, pubKey, scheme,
|
|
+ sending, signature, pwArg);
|
|
+ if (ctx == NULL) {
|
|
+ goto loser;
|
|
+ }
|
|
+
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, context_padding, sizeof(context_padding));
|
|
+ if (rv != SECSuccess) {
|
|
+ goto loser;
|
|
+ }
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, (const unsigned char *)context_string,
|
|
+ /* +1 includes the terminating 0 */
|
|
+ strlen(context_string) + 1);
|
|
+ if (rv != SECSuccess) {
|
|
+ goto loser;
|
|
+ }
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, hashes->u.raw, hashes->len);
|
|
+ if (rv != SECSuccess) {
|
|
+ goto loser;
|
|
+ }
|
|
+ rv = tls_SignOrVerifyEnd(ctx, signature);
|
|
if (rv) {
|
|
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
|
goto loser;
|
|
}
|
|
+ tls_DestroySignOrVerifyContext(ctx);
|
|
+
|
|
+ /* if we are server & sending or !server & !sending, update the scheme */
|
|
+ /* only update on server cert verify */
|
|
+ if (((ss->sec.isServer) ^ sending) == 0){
|
|
+ ss->sec.signatureScheme = scheme;
|
|
+ ss->sec.authType = ssl_SignatureSchemeToAuthType(scheme);
|
|
+ }
|
|
+
|
|
return SECSuccess;
|
|
|
|
loser:
|
|
+ tls_DestroySignOrVerifyContext(ctx);
|
|
+
|
|
return SECFailure;
|
|
}
|
|
|
|
/*
|
|
* Derive-Secret(Secret, Label, Messages) =
|
|
* HKDF-Expand-Label(Secret, Label,
|
|
* Hash(Messages) + Hash(resumption_context), L))
|
|
*/
|
|
@@ -5358,19 +5653,17 @@ loser:
|
|
}
|
|
|
|
SECStatus
|
|
tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey)
|
|
{
|
|
SECStatus rv = SECFailure;
|
|
SECItem buf = { siBuffer, NULL, 0 };
|
|
unsigned int len;
|
|
- SSLHashType hashAlg;
|
|
SSL3Hashes hash;
|
|
- SSL3Hashes tbsHash; /* The hash "to be signed". */
|
|
|
|
PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
|
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
|
|
|
SSL_TRC(3, ("%d: TLS13[%d]: send certificate_verify handshake",
|
|
SSL_GETPID(), ss->fd));
|
|
|
|
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_single);
|
|
@@ -5381,41 +5674,37 @@ tls13_SendCertificateVerify(sslSocket *s
|
|
|
|
/* We should have picked a signature scheme when we received a
|
|
* CertificateRequest, or when we picked a server certificate. */
|
|
PORT_Assert(ss->ssl3.hs.signatureScheme != ssl_sig_none);
|
|
if (ss->ssl3.hs.signatureScheme == ssl_sig_none) {
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
- hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
|
|
- rv = tls13_AddContextToHashes(ss, &hash, hashAlg,
|
|
- PR_TRUE, &tbsHash);
|
|
- if (rv != SECSuccess) {
|
|
- return SECFailure;
|
|
- }
|
|
-
|
|
- rv = ssl3_SignHashes(ss, &tbsHash, privKey, &buf);
|
|
+
|
|
+ rv = tls13_SignOrVerifyHashWithContext(ss, &hash, privKey, NULL,
|
|
+ ss->ssl3.hs.signatureScheme,
|
|
+ PR_TRUE, &buf);
|
|
if (rv == SECSuccess && !ss->sec.isServer) {
|
|
/* Remember the info about the slot that did the signing.
|
|
* Later, when doing an SSL restart handshake, verify this.
|
|
* These calls are mere accessors, and can't fail.
|
|
*/
|
|
PK11SlotInfo *slot;
|
|
sslSessionID *sid = ss->sec.ci.sid;
|
|
|
|
slot = PK11_GetSlotFromPrivateKey(privKey);
|
|
sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
|
|
sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
|
|
sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
|
|
sid->u.ssl3.clAuthValid = PR_TRUE;
|
|
PK11_FreeSlot(slot);
|
|
}
|
|
if (rv != SECSuccess) {
|
|
- goto done; /* err code was set by ssl3_SignHashes */
|
|
+ goto done; /* err code was set by tls13_SignOrVerifyHashWithContext */
|
|
}
|
|
|
|
len = buf.len + 2 + 2;
|
|
|
|
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_verify, len);
|
|
if (rv != SECSuccess) {
|
|
goto done; /* error code set by AppendHandshake */
|
|
}
|
|
@@ -5446,18 +5735,16 @@ SECStatus
|
|
tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|
{
|
|
sslDelegatedCredential *dc = ss->xtnData.peerDelegCred;
|
|
CERTSubjectPublicKeyInfo *spki;
|
|
SECKEYPublicKey *pubKey = NULL;
|
|
SECItem signed_hash = { siBuffer, NULL, 0 };
|
|
SECStatus rv;
|
|
SSLSignatureScheme sigScheme;
|
|
- SSLHashType hashAlg;
|
|
- SSL3Hashes tbsHash;
|
|
SSL3Hashes hashes;
|
|
|
|
SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_verify handshake",
|
|
SSL_GETPID(), ss->fd));
|
|
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
|
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
|
|
|
rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY,
|
|
@@ -5521,23 +5808,16 @@ tls13_HandleCertificateVerify(sslSocket
|
|
}
|
|
|
|
rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme, spki);
|
|
if (rv != SECSuccess) {
|
|
/* Error set already */
|
|
FATAL_ERROR(ss, PORT_GetError(), illegal_parameter);
|
|
return SECFailure;
|
|
}
|
|
- hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
|
|
-
|
|
- rv = tls13_AddContextToHashes(ss, &hashes, hashAlg, PR_FALSE, &tbsHash);
|
|
- if (rv != SECSuccess) {
|
|
- FATAL_ERROR(ss, SSL_ERROR_DIGEST_FAILURE, internal_error);
|
|
- return SECFailure;
|
|
- }
|
|
|
|
rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
|
|
if (rv != SECSuccess) {
|
|
PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
|
|
return SECFailure;
|
|
}
|
|
|
|
if (length != 0) {
|
|
@@ -5545,19 +5825,18 @@ tls13_HandleCertificateVerify(sslSocket
|
|
return SECFailure;
|
|
}
|
|
|
|
pubKey = SECKEY_ExtractPublicKey(spki);
|
|
if (pubKey == NULL) {
|
|
ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
-
|
|
- rv = ssl_VerifySignedHashesWithPubKey(ss, pubKey, sigScheme,
|
|
- &tbsHash, &signed_hash);
|
|
+ rv = tls13_SignOrVerifyHashWithContext(ss, &hashes, NULL, pubKey,
|
|
+ sigScheme, PR_FALSE, &signed_hash);
|
|
if (rv != SECSuccess) {
|
|
FATAL_ERROR(ss, PORT_GetError(), decrypt_error);
|
|
goto loser;
|
|
}
|
|
|
|
/* Set the auth type and verify it is what we captured in ssl3_AuthCertificate */
|
|
if (!ss->sec.isServer) {
|
|
ss->sec.authType = ssl_SignatureSchemeToAuthType(sigScheme);
|
|
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
|
|
--- a/lib/ssl/tls13exthandle.c
|
|
+++ b/lib/ssl/tls13exthandle.c
|
|
@@ -1467,17 +1467,17 @@ tls13_ClientSendDelegatedCredentialsXtn(
|
|
}
|
|
|
|
/* Filter the schemes that are enabled and acceptable. Save these in
|
|
* the "advertised" list, then encode them to be sent. If we receive
|
|
* a DC in response, validate that it matches one of the advertised
|
|
* schemes. */
|
|
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
|
unsigned int filteredCount = 0;
|
|
- SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max,
|
|
+ SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.min, ss->vrange.max,
|
|
PR_TRUE /* disableRsae */,
|
|
PR_FALSE /* forCert */,
|
|
MAX_SIGNATURE_SCHEMES,
|
|
filtered,
|
|
&filteredCount);
|
|
if (rv != SECSuccess) {
|
|
return SECFailure;
|
|
}
|
|
diff --git a/lib/ssl/tls13subcerts.c b/lib/ssl/tls13subcerts.c
|
|
--- a/lib/ssl/tls13subcerts.c
|
|
+++ b/lib/ssl/tls13subcerts.c
|
|
@@ -281,30 +281,31 @@ tls13_AppendCredentialSignature(sslBuffe
|
|
return SECFailure;
|
|
}
|
|
|
|
return SECSuccess;
|
|
}
|
|
|
|
/* Hashes the message used to sign/verify the DC. */
|
|
static SECStatus
|
|
-tls13_HashCredentialSignatureMessage(SSL3Hashes *hash,
|
|
- SSLSignatureScheme scheme,
|
|
- const CERTCertificate *cert,
|
|
- const sslBuffer *dcBuf)
|
|
+tls13_HashCredentialAndSignOrVerifyMessage(SECKEYPrivateKey *privKey,
|
|
+ SECKEYPublicKey *pubKey,
|
|
+ SSLSignatureScheme scheme,
|
|
+ PRBool signing,
|
|
+ const CERTCertificate *cert,
|
|
+ const sslBuffer *dcBuf,
|
|
+ SECItem *signature, void *pwArg)
|
|
{
|
|
SECStatus rv;
|
|
- PK11Context *ctx = NULL;
|
|
- unsigned int hashLen;
|
|
+ tlsSignOrVerifyContext *ctx = NULL;
|
|
|
|
- /* Set up hash context. */
|
|
- hash->hashAlg = ssl_SignatureSchemeToHashType(scheme);
|
|
- ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(hash->hashAlg));
|
|
+ /* Set up sign and hash context. */
|
|
+ ctx = tls_SignOrVerifyGetNewContext(privKey, pubKey, scheme, signing,
|
|
+ signature, pwArg);
|
|
if (!ctx) {
|
|
- PORT_SetError(SEC_ERROR_NO_MEMORY);
|
|
goto loser;
|
|
}
|
|
|
|
static const PRUint8 kCtxStrPadding[64] = {
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
@@ -312,73 +313,62 @@ tls13_HashCredentialSignatureMessage(SSL
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
|
|
};
|
|
|
|
static const PRUint8 kCtxStr[] = "TLS, server delegated credentials";
|
|
|
|
/* Hash the message signed by the peer. */
|
|
- rv = SECSuccess;
|
|
- rv |= PK11_DigestBegin(ctx);
|
|
- rv |= PK11_DigestOp(ctx, kCtxStrPadding, sizeof kCtxStrPadding);
|
|
- rv |= PK11_DigestOp(ctx, kCtxStr, 1 /* 0-byte */ + strlen((const char *)kCtxStr));
|
|
- rv |= PK11_DigestOp(ctx, cert->derCert.data, cert->derCert.len);
|
|
- rv |= PK11_DigestOp(ctx, dcBuf->buf, dcBuf->len);
|
|
- rv |= PK11_DigestFinal(ctx, hash->u.raw, &hashLen, sizeof hash->u.raw);
|
|
- if (rv != SECSuccess) {
|
|
- PORT_SetError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
|
- goto loser;
|
|
- }
|
|
-
|
|
- hash->len = hashLen;
|
|
- if (ctx) {
|
|
- PK11_DestroyContext(ctx, PR_TRUE);
|
|
- }
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, kCtxStrPadding, sizeof kCtxStrPadding);
|
|
+ if (rv != SECSuccess) goto loser;
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, kCtxStr,
|
|
+ 1 /* 0-byte */ + strlen((const char *)kCtxStr));
|
|
+ if (rv != SECSuccess) goto loser;
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, cert->derCert.data, cert->derCert.len);
|
|
+ if (rv != SECSuccess) goto loser;
|
|
+ rv = tls_SignOrVerifyUpdate(ctx, dcBuf->buf, dcBuf->len);
|
|
+ if (rv != SECSuccess) goto loser;
|
|
+ rv = tls_SignOrVerifyEnd(ctx, signature);
|
|
+ if (rv != SECSuccess) goto loser;
|
|
+ tls_DestroySignOrVerifyContext(ctx);
|
|
return SECSuccess;
|
|
|
|
loser:
|
|
- if (ctx) {
|
|
- PK11_DestroyContext(ctx, PR_TRUE);
|
|
- }
|
|
+ tls_DestroySignOrVerifyContext(ctx);
|
|
return SECFailure;
|
|
}
|
|
|
|
/* Verifies the DC signature. */
|
|
static SECStatus
|
|
tls13_VerifyCredentialSignature(sslSocket *ss, sslDelegatedCredential *dc)
|
|
{
|
|
SECStatus rv = SECSuccess;
|
|
- SSL3Hashes hash;
|
|
sslBuffer dcBuf = SSL_BUFFER_EMPTY;
|
|
CERTCertificate *cert = ss->sec.peerCert;
|
|
SECKEYPublicKey *pubKey = NULL;
|
|
+ void *pwArg = ss->pkcs11PinArg;
|
|
+
|
|
|
|
/* Serialize the DC parameters. */
|
|
rv = tls13_AppendCredentialParams(&dcBuf, dc);
|
|
if (rv != SECSuccess) {
|
|
goto loser; /* Error set by caller. */
|
|
}
|
|
|
|
- /* Hash the message that was signed by the delegator. */
|
|
- rv = tls13_HashCredentialSignatureMessage(&hash, dc->alg, cert, &dcBuf);
|
|
- if (rv != SECSuccess) {
|
|
- FATAL_ERROR(ss, PORT_GetError(), internal_error);
|
|
- goto loser;
|
|
- }
|
|
-
|
|
pubKey = SECKEY_ExtractPublicKey(&cert->subjectPublicKeyInfo);
|
|
if (pubKey == NULL) {
|
|
FATAL_ERROR(ss, SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE, internal_error);
|
|
goto loser;
|
|
}
|
|
|
|
- /* Verify the signature of the message. */
|
|
- rv = ssl_VerifySignedHashesWithPubKey(ss, pubKey, dc->alg,
|
|
- &hash, &dc->signature);
|
|
+ /* Verify the signature of the delegaor message. */
|
|
+ rv = tls13_HashCredentialAndSignOrVerifyMessage(NULL, pubKey, dc->alg,
|
|
+ PR_FALSE, cert, &dcBuf,
|
|
+ &dc->signature, pwArg);
|
|
if (rv != SECSuccess) {
|
|
FATAL_ERROR(ss, SSL_ERROR_DC_BAD_SIGNATURE, illegal_parameter);
|
|
goto loser;
|
|
}
|
|
|
|
SECOidTag spkiAlg = SECOID_GetAlgorithmTag(&(dc->spki->algorithm));
|
|
if (spkiAlg == SEC_OID_PKCS1_RSA_ENCRYPTION) {
|
|
FATAL_ERROR(ss, SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, illegal_parameter);
|
|
@@ -651,17 +641,23 @@ tls13_MakeDcSpki(const SECKEYPublicKey *
|
|
return NULL;
|
|
}
|
|
if (keyScheme != dcCertVerifyAlg) {
|
|
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
|
|
return NULL;
|
|
}
|
|
return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
|
|
}
|
|
-
|
|
+ case mldsaKey:
|
|
+ if (ssl_SignatureSchemeFromPublicKeyOid(dcPub->u.mldsa.params)
|
|
+ != dcCertVerifyAlg) {
|
|
+ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
|
|
+ return NULL;
|
|
+ }
|
|
+ return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
|
|
default:
|
|
break;
|
|
}
|
|
|
|
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
|
return NULL;
|
|
}
|
|
|
|
@@ -683,19 +679,19 @@ SSLExp_DelegateCredential(const CERTCert
|
|
const SECKEYPrivateKey *certPriv,
|
|
const SECKEYPublicKey *dcPub,
|
|
SSLSignatureScheme dcCertVerifyAlg,
|
|
PRUint32 dcValidFor,
|
|
PRTime now,
|
|
SECItem *out)
|
|
{
|
|
SECStatus rv;
|
|
- SSL3Hashes hash;
|
|
CERTSubjectPublicKeyInfo *spki = NULL;
|
|
SECKEYPrivateKey *tmpPriv = NULL;
|
|
+ void *pwArg = certPriv->wincx;
|
|
sslDelegatedCredential *dc = NULL;
|
|
sslBuffer dcBuf = SSL_BUFFER_EMPTY;
|
|
|
|
if (!cert || !certPriv || !dcPub || !out) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return SECFailure;
|
|
}
|
|
|
|
@@ -749,30 +745,27 @@ SSLExp_DelegateCredential(const CERTCert
|
|
}
|
|
PORT_Assert(dc->alg != ssl_sig_none);
|
|
|
|
rv = tls13_AppendCredentialParams(&dcBuf, dc);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
|
|
- /* Hash signature message. */
|
|
- rv = tls13_HashCredentialSignatureMessage(&hash, dc->alg, cert, &dcBuf);
|
|
- if (rv != SECSuccess) {
|
|
- goto loser;
|
|
- }
|
|
|
|
/* Sign the hash with the delegation key.
|
|
*
|
|
* The PK11 API discards const qualifiers, so we have to make a copy of
|
|
- * |certPriv| and pass the copy to |ssl3_SignHashesWithPrivKey|.
|
|
+ * |certPriv| and pass the copy to
|
|
+ * |tls3_HashCredentialAndSignOrVerifyMessage|.
|
|
*/
|
|
tmpPriv = SECKEY_CopyPrivateKey(certPriv);
|
|
- rv = ssl3_SignHashesWithPrivKey(&hash, tmpPriv, dc->alg,
|
|
- PR_TRUE /* isTls */, &dc->signature);
|
|
+ rv = tls13_HashCredentialAndSignOrVerifyMessage(tmpPriv, NULL, dc->alg,
|
|
+ PR_TRUE, cert, &dcBuf,
|
|
+ &dc->signature, pwArg);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
|
|
/* Serialize the DC signature. */
|
|
rv = tls13_AppendCredentialSignature(&dcBuf, dc);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
diff --git a/tests/cert/cert.sh b/tests/cert/cert.sh
|
|
--- a/tests/cert/cert.sh
|
|
+++ b/tests/cert/cert.sh
|
|
@@ -627,41 +627,67 @@ cert_all_CA()
|
|
#
|
|
# Create ML-DSA-44 version of TestCA
|
|
ALL_CU_SUBJECT="CN=NSS Test CA (ML-DSA-44), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-44 $CADIR TestCA-ml-dsa-44 -x "CTu,CTu,CTu" ${D_CA} "1"
|
|
#
|
|
# Create ML-DSA-44 versions of the intermediate CA certs
|
|
ALL_CU_SUBJECT="CN=NSS Server Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-44 $SERVER_CADIR serverCA-ml-dsa-44 -x "Cu,Cu,Cu" ${D_SERVER_CA} "2"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-44 $SERVER_CADIR chain-1-serverCA-ml-dsa-44 "-c serverCA-ml-dsa-44" "u,u,u" ${D_SERVER_CA} "3"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-44 $SERVER_CADIR chain-2-serverCA-ml-dsa-44 "-c chain-1-serverCA-ml-dsa-44" "u,u,u" ${D_SERVER_CA} "4"
|
|
|
|
ALL_CU_SUBJECT="CN=NSS Client Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
- cert_m_ldsa_CA ml-dsa-44 $CLIENT_CADIR clientCA-dsa -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ cert_ml_dsa_CA ml-dsa-44 $CLIENT_CADIR clientCA-ml-dsa-44 -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-44 $CLIENT_CADIR chain-1-clientCA-ml-dsa-44 "-c clientCA-ml-dsa-44" "u,u,u" ${D_CLIENT_CA} "6"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ML-DSA-44), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-44 $CLIENT_CADIR chain-2-clientCA-ml-dsa-44 "-c chain-1-clientCA-ml-dsa-44" "u,u,u" ${D_CLIENT_CA} "7"
|
|
+
|
|
#
|
|
# Create ML-DSA-65 version of TestCA
|
|
ALL_CU_SUBJECT="CN=NSS Test CA (ML-DSA-65), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-65 $CADIR TestCA-ml-dsa-65 -x "CTu,CTu,CTu" ${D_CA} "1"
|
|
-#
|
|
# Create ML-DSA-65 versions of the intermediate CA certs
|
|
ALL_CU_SUBJECT="CN=NSS Server Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-65 $SERVER_CADIR serverCA-ml-dsa-65 -x "Cu,Cu,Cu" ${D_SERVER_CA} "2"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-65 $SERVER_CADIR chain-1-serverCA-ml-dsa-65 "-c serverCA-ml-dsa-65" "u,u,u" ${D_SERVER_CA} "3"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-65 $SERVER_CADIR chain-2-serverCA-ml-dsa-65 "-c chain-1-serverCA-ml-dsa-65" "u,u,u" ${D_SERVER_CA} "4"
|
|
+#
|
|
|
|
ALL_CU_SUBJECT="CN=NSS Client Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
- cert_m_ldsa_CA ml-dsa-65 $CLIENT_CADIR clientCA-dsa -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ cert_ml_dsa_CA ml-dsa-65 $CLIENT_CADIR clientCA-ml-dsa-65 -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-65 $CLIENT_CADIR chain-1-clientCA-ml-dsa-65 "-c clientCA-ml-dsa-65" "u,u,u" ${D_CLIENT_CA} "6"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ML-DSA-65), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-65 $CLIENT_CADIR chain-2-clientCA-ml-dsa-65 "-c chain-1-clientCA-ml-dsa-65" "u,u,u" ${D_CLIENT_CA} "7"
|
|
#
|
|
# Create ML-DSA-87 version of TestCA
|
|
ALL_CU_SUBJECT="CN=NSS Test CA (ML-DSA-87), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-87 $CADIR TestCA-ml-dsa-87 -x "CTu,CTu,CTu" ${D_CA} "1"
|
|
#
|
|
# Create ML-DSA-87 versions of the intermediate CA certs
|
|
ALL_CU_SUBJECT="CN=NSS Server Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
cert_ml_dsa_CA ml-dsa-87 $SERVER_CADIR serverCA-ml-dsa-87 -x "Cu,Cu,Cu" ${D_SERVER_CA} "2"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-87 $SERVER_CADIR chain-1-serverCA-ml-dsa-87 "-c serverCA-ml-dsa-87" "u,u,u" ${D_SERVER_CA} "3"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-87 $SERVER_CADIR chain-2-serverCA-ml-dsa-87 "-c chain-1-serverCA-ml-dsa-87" "u,u,u" ${D_SERVER_CA} "4"
|
|
+#
|
|
|
|
ALL_CU_SUBJECT="CN=NSS Client Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
- cert_m_ldsa_CA ml-dsa-87 $CLIENT_CADIR clientCA-dsa -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ cert_ml_dsa_CA ml-dsa-87 $CLIENT_CADIR clientCA-ml-dsa-87 -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-87 $CLIENT_CADIR chain-1-clientCA-ml-dsa-87 "-c clientCA-ml-dsa-87" "u,u,u" ${D_CLIENT_CA} "6"
|
|
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ML-DSA-87), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
|
|
+ cert_ml_dsa_CA ml-dsa-87 $CLIENT_CADIR chain-2-clientCA-ml-dsa-87 "-c chain-1-clientCA-ml-dsa-87" "u,u,u" ${D_CLIENT_CA} "7"
|
|
|
|
fi
|
|
|
|
#
|
|
# Create RSA-PSS version of TestCA
|
|
ALL_CU_SUBJECT="CN=NSS Test CA (RSA-PSS), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
cert_rsa_pss_CA $CADIR TestCA-rsa-pss -x "CTu,CTu,CTu" ${D_CA} "1" SHA256
|
|
rm $CADIR/rsapssroot.cert
|
|
@@ -1223,16 +1249,81 @@ cert_extended_ssl()
|
|
certu -A -n "${CERTNAME}-dsamixed" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
-f "${R_PWFILE}" -i "${CERTNAME}-dsamixed.cert" 2>&1
|
|
|
|
# CU_ACTION="Import Client mixed DSA Root CA -t T,, for $CERTNAME (ext.)"
|
|
# certu -A -n "clientCA-dsamixed" -t "T,," -f "${R_PWFILE}" \
|
|
# -d "${PROFILEDIR}" -i "${CLIENT_CADIR}/clientCA-dsamixed.ca.cert" \
|
|
# 2>&1
|
|
fi
|
|
+ if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+#
|
|
+# Repeat the above for ML-DSA-44 certs
|
|
+#
|
|
+ CU_ACTION="Generate ML-DSA-44 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-44@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-44 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-44 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${SERVER_CADIR}
|
|
+ certu -C -c "chain-2-serverCA-ml-dsa-44" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-44.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-44 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-44" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-44.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Client ML-DSA-44 Root CA -t T,, for $CERTNAME (ext.)"
|
|
+ certu -A -n "clientCA-ml-dsa-44" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
|
|
+ -i "${CLIENT_CADIR}/clientCA-ml-dsa-44.ca.cert" 2>&1
|
|
+#
|
|
+# Repeat the above for ML-DSA-65 certs
|
|
+#
|
|
+ CU_ACTION="Generate ML-DSA-65 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-65@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-65 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-65 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${SERVER_CADIR}
|
|
+ certu -C -c "chain-2-serverCA-ml-dsa-65" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-65.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-65 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-65" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-65.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Client ML-DSA-65 Root CA -t T,, for $CERTNAME (ext.)"
|
|
+ certu -A -n "clientCA-ml-dsa-65" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
|
|
+ -i "${CLIENT_CADIR}/clientCA-ml-dsa-65.ca.cert" 2>&1
|
|
+#
|
|
+# Repeat the above for ML-DSA-87 certs
|
|
+#
|
|
+ CU_ACTION="Generate ML-DSA-87 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-87@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-87 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-87 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${SERVER_CADIR}
|
|
+ certu -C -c "chain-2-serverCA-ml-dsa-87" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-87.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-87 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-87" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-87.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Client ML-DSA-87 Root CA -t T,, for $CERTNAME (ext.)"
|
|
+ certu -A -n "clientCA-ml-dsa-87" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
|
|
+ -i "${CLIENT_CADIR}/clientCA-ml-dsa-87.ca.cert" 2>&1
|
|
+#
|
|
+# done with ML-DSA certs
|
|
+#
|
|
+ fi
|
|
|
|
#
|
|
# Repeat the above for EC certs
|
|
#
|
|
EC_CURVE="secp256r1"
|
|
CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)"
|
|
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \
|
|
@@ -1293,17 +1384,17 @@ cert_extended_ssl()
|
|
|
|
TESTNAME="Ensure there's zero matches for ${CERTNAME}-repeated-ecmixed"
|
|
cert_check_nickname_exists "$MYDBPASS" "${CERTNAME}-repeated-ecmixed" 0 0 "${TESTNAME}"
|
|
|
|
echo "Importing all the server's own CA chain into the servers DB"
|
|
for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ;
|
|
do
|
|
N=`basename $CA | sed -e "s/.ca.cert//"`
|
|
- if [ $N = "serverCA" -o $N = "serverCA-ec" -o $N = "serverCA-dsa" ] ; then
|
|
+ if [ $N = "serverCA" -o $N = "serverCA-ec" -o $N = "serverCA-dsa" -o $N = "serverCA-ml-dsa-44" -o $N = "serverCA-ml-dsa-65" -o $N = "serverCA-ml-dsa-87" ] ; then
|
|
T="-t C,C,C"
|
|
else
|
|
T="-t u,u,u"
|
|
fi
|
|
CU_ACTION="Import $N CA $T for $CERTNAME (ext.) "
|
|
certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
|
|
-i "${CA}" 2>&1
|
|
done
|
|
@@ -1377,16 +1468,79 @@ cert_extended_ssl()
|
|
|
|
# CU_ACTION="Import Server DSA Root CA -t C,C,C for $CERTNAME (ext.)"
|
|
# certu -A -n "serverCA-dsa" -t "C,C,C" -f "${R_PWFILE}" \
|
|
# -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-dsa.ca.cert" 2>&1
|
|
#
|
|
# done with mixed DSA certs
|
|
#
|
|
fi
|
|
+#
|
|
+# Repeat the above for ML-DSA certs
|
|
+#
|
|
+ if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+# ML-DSA-44 certs
|
|
+ CU_ACTION="Generate ML-DSA-44 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-44@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-44 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-44 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
|
|
+ certu -C -c "chain-2-clientCA-ml-dsa-44" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-44.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-44 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-44" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-44.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Server ML-DSA-44 Root CA -t C,C,C for $CERTNAME (ext.)"
|
|
+ certu -A -n "serverCA-ml-dsa-44" -t "C,C,C" -f "${R_PWFILE}" \
|
|
+ -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-ml-dsa-44.ca.cert" 2>&1
|
|
+# ML-DSA-65 certs
|
|
+ CU_ACTION="Generate ML-DSA-65 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-65@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-65 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-65 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
|
|
+ certu -C -c "chain-2-clientCA-ml-dsa-65" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-65.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-65 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-65" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-65.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Server ML-DSA-65 Root CA -t C,C,C for $CERTNAME (ext.)"
|
|
+ certu -A -n "serverCA-ml-dsa-65" -t "C,C,C" -f "${R_PWFILE}" \
|
|
+ -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-ml-dsa-65.ca.cert" 2>&1
|
|
+# ML-DSA-87 certs
|
|
+ CU_ACTION="Generate ML-DSA-87 Cert Request for $CERTNAME (ext)"
|
|
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ml-dsa-87@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
+ certu -R -d "${PROFILEDIR}" -k mldsa -q ml-dsa-87 -f "${R_PWFILE}" \
|
|
+ -z "${R_NOISE_FILE}" -o req 2>&1
|
|
+
|
|
+ CU_ACTION="Sign ${CERTNAME}'s ML-DSA-87 Request (ext)"
|
|
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
|
|
+ certu -C -c "chain-2-clientCA-ml-dsa-87" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
|
|
+ -i req -o "${CERTNAME}-ml-dsa-87.cert" -f "${R_PWFILE}" 2>&1
|
|
+
|
|
+ CU_ACTION="Import $CERTNAME's ML-DSA-87 Cert -t u,u,u (ext)"
|
|
+ certu -A -n "${CERTNAME}-ml-dsa-87" -t "u,u,u" -d "${PROFILEDIR}" \
|
|
+ -f "${R_PWFILE}" -i "${CERTNAME}-ml-dsa-87.cert" 2>&1
|
|
+
|
|
+ CU_ACTION="Import Server ML-DSA-87 Root CA -t C,C,C for $CERTNAME (ext.)"
|
|
+ certu -A -n "serverCA-ml-dsa-87" -t "C,C,C" -f "${R_PWFILE}" \
|
|
+ -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-ml-dsa-87.ca.cert" 2>&1
|
|
+#
|
|
+# done with ML-DSA certs
|
|
+#
|
|
+#
|
|
+ fi
|
|
|
|
#
|
|
# Repeat the above for EC certs
|
|
#
|
|
CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)"
|
|
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
|
certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \
|
|
-z "${R_NOISE_FILE}" -o req 2>&1
|
|
@@ -1429,17 +1583,17 @@ cert_extended_ssl()
|
|
#
|
|
# done with mixed EC certs
|
|
#
|
|
|
|
echo "Importing all the client's own CA chain into the servers DB"
|
|
for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ;
|
|
do
|
|
N=`basename $CA | sed -e "s/.ca.cert//"`
|
|
- if [ $N = "clientCA" -o $N = "clientCA-ec" -o $N = "clientCA-dsa" ] ; then
|
|
+ if [ $N = "clientCA" -o $N = "clientCA-ec" -o $N = "clientCA-dsa" -o $N = "clientCA-ml-dsa-44" -o $N = "clientCA-ml-dsa-65" -o $N = "clientCA-ml-dsa-87" ] ; then
|
|
T="-t T,C,C"
|
|
else
|
|
T="-t u,u,u"
|
|
fi
|
|
CU_ACTION="Import $N CA $T for $CERTNAME (ext.)"
|
|
certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
|
|
-i "${CA}" 2>&1
|
|
done
|
|
@@ -2046,16 +2200,52 @@ update=$CRLUPDATE
|
|
addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE
|
|
addext reasonCode 0 4
|
|
addext issuerAltNames 0 "rfc822Name:ca-dsaemail@ca.com|dnsName:ca-dsa.com|directoryName:CN=NSS Test CA (DSA),O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca-dsa.com|ipAddress:192.168.0.1|registerID=reg CA (DSA)"
|
|
EOF_CRLINI
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
chmod 600 ${CRL_FILE_GRP_1}_or-dsa
|
|
fi
|
|
|
|
+if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+ CU_ACTION="Generating CRL (ML-DSA-44) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ml-dsa-44 authority"
|
|
+# Until Bug 292285 is resolved, do not encode x400 Addresses. After
|
|
+# the bug is resolved, reintroduce "x400Address:x400Address" within
|
|
+# addext issuerAltNames ...
|
|
+ crlu -q -d $CADIR -G -n "TestCA-ml-dsa-44" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or-ml-dsa-44 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE
|
|
+addext reasonCode 0 4
|
|
+addext issuerAltNames 0 "rfc822Name:ca-ml-dsa-44email@ca.com|dnsName:ca-ml-dsa-44.com|directoryName:CN=NSS Test CA (ML-DSA-44),O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca-dsa.com|ipAddress:192.168.0.1|registerID=reg CA (ML-DSA-44)"
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or-ml-dsa-44
|
|
+ CU_ACTION="Generating CRL (ML-DSA-65) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ml-dsa-65 authority"
|
|
+ crlu -q -d $CADIR -G -n "TestCA-ml-dsa-65" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or-ml-dsa-65 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE
|
|
+addext reasonCode 0 4
|
|
+addext issuerAltNames 0 "rfc822Name:ca-ml-dsa-65email@ca.com|dnsName:ca-ml-dsa-65.com|directoryName:CN=NSS Test CA (ML-DSA-65),O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca-dsa.com|ipAddress:192.168.0.1|registerID=reg CA (ML-DSA-65)"
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or-ml-dsa-65
|
|
+ CU_ACTION="Generating CRL (ML-DSA-87) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ml-dsa-87 authority"
|
|
+ crlu -q -d $CADIR -G -n "TestCA-ml-dsa-87" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or-ml-dsa-87 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE
|
|
+addext reasonCode 0 4
|
|
+addext issuerAltNames 0 "rfc822Name:ca-ml-dsa-87email@ca.com|dnsName:ca-ml-dsa-87.com|directoryName:CN=NSS Test CA (ML-DSA-87),O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca-dsa.com|ipAddress:192.168.0.1|registerID=reg CA (ML-DSA-87)"
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or-ml-dsa-87
|
|
+fi
|
|
+
|
|
|
|
|
|
CU_ACTION="Generating CRL (ECC) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ec authority"
|
|
|
|
# Until Bug 292285 is resolved, do not encode x400 Addresses. After
|
|
# the bug is resolved, reintroduce "x400Address:x400Address" within
|
|
# addext issuerAltNames ...
|
|
crlu -q -d $CADIR -G -n "TestCA-ec" -f ${R_PWFILE} \
|
|
@@ -2092,16 +2282,54 @@ EOF_CRLINI
|
|
-i ${CRL_FILE_GRP_1}_or-dsa <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_END} $CRL_GRP_DATE
|
|
EOF_CRLINI
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
chmod 600 ${CRL_FILE_GRP_1}_or1-dsa
|
|
TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-dsa"
|
|
fi
|
|
+if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+ CU_ACTION="Modify CRL (ML-DSA-44) by adding one more cert"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-44" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or1-ml-dsa-44 \
|
|
+ -i ${CRL_FILE_GRP_1}_or-ml-dsa-44 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_END} $CRL_GRP_DATE
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or1-ml-dsa-44
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ml-dsa-44"
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or1-ml-dsa-65
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ml-dsa-65"
|
|
+ CU_ACTION="Modify CRL (ML-DSA-65) by adding one more cert"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-65" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or1-ml-dsa-65 \
|
|
+ -i ${CRL_FILE_GRP_1}_or-ml-dsa-65 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_END} $CRL_GRP_DATE
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or1-ml-dsa-65
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ml-dsa-65"
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or1-ml-dsa-87
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ml-dsa-87"
|
|
+ CU_ACTION="Modify CRL (ML-DSA-87) by adding one more cert"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-87" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_1}_or1-ml-dsa-87 \
|
|
+ -i ${CRL_FILE_GRP_1}_or-ml-dsa-87 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_END} $CRL_GRP_DATE
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_1}_or1-ml-dsa-87
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ml-dsa-87"
|
|
+fi
|
|
|
|
|
|
CU_ACTION="Modify CRL (ECC) by adding one more cert"
|
|
crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} \
|
|
-o ${CRL_FILE_GRP_1}_or1-ec -i ${CRL_FILE_GRP_1}_or-ec <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_END} $CRL_GRP_DATE
|
|
EOF_CRLINI
|
|
@@ -2122,25 +2350,57 @@ EOF_CRLINI
|
|
chmod 600 ${CRL_FILE_GRP_1}
|
|
TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1"
|
|
|
|
|
|
if [ -z "$NSS_DISABLE_DSA" ]; then
|
|
CU_ACTION="Modify CRL (DSA) by removing one cert"
|
|
sleep 2
|
|
CRLUPDATE=`date -u "+%Y%m%d%H%M%SZ"`
|
|
- crlu -d $CADIR -M -n "TestCA-dsa" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1} \
|
|
- -i ${CRL_FILE_GRP_1}_or1 <<EOF_CRLINI
|
|
+ crlu -d $CADIR -M -n "TestCA-dsa" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-dsa \
|
|
+ -i ${CRL_FILE_GRP_1}_or1-dsa <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_1}
|
|
+EOF_CRLINI
|
|
+ chmod 600 ${CRL_FILE_GRP_1}-dsa
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-dsa"
|
|
+ fi
|
|
+
|
|
+if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+ CU_ACTION="Modify CRL (ML-DSA-44) by removing one cert"
|
|
+ sleep 2
|
|
+ CRLUPDATE=`date -u "+%Y%m%d%H%M%SZ"`
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-44" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ml-dsa-44 \
|
|
+ -i ${CRL_FILE_GRP_1}_or1-ml-dsa-44 <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
rmcert ${UNREVOKED_CERT_GRP_1}
|
|
EOF_CRLINI
|
|
- chmod 600 ${CRL_FILE_GRP_1}
|
|
- TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-dsa"
|
|
- fi
|
|
-
|
|
+ chmod 600 ${CRL_FILE_GRP_1}-ml-dsa-44
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-ml-dsa-44"
|
|
+ CU_ACTION="Modify CRL (ML-DSA-65) by removing one cert"
|
|
+ sleep 2
|
|
+ CRLUPDATE=`date -u "+%Y%m%d%H%M%SZ"`
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-65" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ml-dsa-65 \
|
|
+ -i ${CRL_FILE_GRP_1}_or1-ml-dsa-65 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_1}
|
|
+EOF_CRLINI
|
|
+ chmod 600 ${CRL_FILE_GRP_1}-ml-dsa-65
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-ml-dsa-65"
|
|
+ CU_ACTION="Modify CRL (ML-DSA-87) by removing one cert"
|
|
+ sleep 2
|
|
+ CRLUPDATE=`date -u "+%Y%m%d%H%M%SZ"`
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-87" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ml-dsa-87 \
|
|
+ -i ${CRL_FILE_GRP_1}_or1-ml-dsa-87 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_1}
|
|
+EOF_CRLINI
|
|
+ chmod 600 ${CRL_FILE_GRP_1}-ml-dsa-87
|
|
+ TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-ml-dsa-87"
|
|
+fi
|
|
|
|
|
|
CU_ACTION="Modify CRL (ECC) by removing one cert"
|
|
crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ec \
|
|
-i ${CRL_FILE_GRP_1}_or1-ec <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
rmcert ${UNREVOKED_CERT_GRP_1}
|
|
EOF_CRLINI
|
|
@@ -2160,16 +2420,53 @@ EOF_CRLINI
|
|
-i ${CRL_FILE_GRP_1} <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
addext invalidityDate 0 $CRLUPDATE
|
|
rmcert ${UNREVOKED_CERT_GRP_2}
|
|
EOF_CRLINI
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
chmod 600 ${CRL_FILE_GRP_2}
|
|
+
|
|
+if [ -n "${NSS_ENABLE_ML_DSA}" ]; then
|
|
+ CU_ACTION="Creating CRL (ML_DSA-44) for groups 1 and 2"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-44" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_2}-ml-dsa-44 \
|
|
+ -i ${CRL_FILE_GRP_1}-ml-dsa-44 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+addext invalidityDate 0 $CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_2}
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_2}-ml-dsa-65
|
|
+ CU_ACTION="Creating CRL (ML_DSA-65) for groups 1 and 2"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-65" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_2}-ml-dsa-65 \
|
|
+ -i ${CRL_FILE_GRP_1}-ml-dsa-65 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+addext invalidityDate 0 $CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_2}
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_2}-ml-dsa-65
|
|
+ CU_ACTION="Creating CRL (ML_DSA-87) for groups 1 and 2"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-87" -f ${R_PWFILE} \
|
|
+ -o ${CRL_FILE_GRP_2}-ml-dsa-87 \
|
|
+ -i ${CRL_FILE_GRP_1}-ml-dsa-87 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+addext invalidityDate 0 $CRLUPDATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_2}
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_2}-ml-dsa-87
|
|
+fi
|
|
+
|
|
CU_ACTION="Creating CRL (ECC) for groups 1 and 2"
|
|
crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_2}-ec \
|
|
-i ${CRL_FILE_GRP_1}-ec <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
addext invalidityDate 0 $CRLUPDATE
|
|
rmcert ${UNREVOKED_CERT_GRP_2}
|
|
EOF_CRLINI
|
|
@@ -2191,16 +2488,49 @@ EOF_CRLINI
|
|
-i ${CRL_FILE_GRP_2} <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
rmcert ${UNREVOKED_CERT_GRP_3}
|
|
addext crlNumber 0 2
|
|
EOF_CRLINI
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
chmod 600 ${CRL_FILE_GRP_3}
|
|
+
|
|
+if [ -n "${NSS_ENABLE_ML_DSA}" ]; then
|
|
+ CU_ACTION="Creating CRL (ML-DSA-44) for groups 1, 2 and 3"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-44" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ml-dsa-44 \
|
|
+ -i ${CRL_FILE_GRP_2}-ml-dsa-44 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_3}
|
|
+addext crlNumber 0 2
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_3}-ml-dsa-44
|
|
+ CU_ACTION="Creating CRL (ML-DSA-65) for groups 1, 2 and 3"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-65" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ml-dsa-65 \
|
|
+ -i ${CRL_FILE_GRP_2}-ml-dsa-65 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_3}
|
|
+addext crlNumber 0 2
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_3}-ml-dsa-65
|
|
+ CU_ACTION="Creating CRL (ML-DSA-87) for groups 1, 2 and 3"
|
|
+ crlu -d $CADIR -M -n "TestCA-ml-dsa-87" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ml-dsa-87 \
|
|
+ -i ${CRL_FILE_GRP_2}-ml-dsa-87 <<EOF_CRLINI
|
|
+update=$CRLUPDATE
|
|
+addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
+rmcert ${UNREVOKED_CERT_GRP_3}
|
|
+addext crlNumber 0 2
|
|
+EOF_CRLINI
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ chmod 600 ${CRL_FILE_GRP_3}-ml-dsa-87
|
|
+fi
|
|
CU_ACTION="Creating CRL (ECC) for groups 1, 2 and 3"
|
|
crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ec \
|
|
-i ${CRL_FILE_GRP_2}-ec <<EOF_CRLINI
|
|
update=$CRLUPDATE
|
|
addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
|
|
rmcert ${UNREVOKED_CERT_GRP_3}
|
|
addext crlNumber 0 2
|
|
EOF_CRLINI
|
|
@@ -2209,16 +2539,35 @@ EOF_CRLINI
|
|
|
|
############ Importing Server CA Issued CRL for certs of first group #######
|
|
|
|
echo "$SCRIPTNAME: Importing Server CA Issued CRL for certs ${CRL_GRP_BEGIN} trough ${CRL_GRP_END}"
|
|
CU_ACTION="Importing CRL for groups 1"
|
|
crlu -D -n TestCA -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
crlu -I -i ${CRL_FILE} -n "TestCA" -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+
|
|
+if [ -n "${NSS_ENABLE_ML_DSA}" ]; then
|
|
+ CU_ACTION="Importing CRL (ML-DSA-44) for groups 1"
|
|
+ crlu -D -n TestCA-ml-dsa-44 -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
+ crlu -I -i ${CRL_FILE}-ml-dsa-44 -n "TestCA-ml-dsa-44" -f "${R_PWFILE}" \
|
|
+ -d "${R_SERVERDIR}"
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ CU_ACTION="Importing CRL (ML-DSA-65) for groups 1"
|
|
+ crlu -D -n TestCA-ml-dsa-65 -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
+ crlu -I -i ${CRL_FILE}-ml-dsa-65 -n "TestCA-ml-dsa-65" -f "${R_PWFILE}" \
|
|
+ -d "${R_SERVERDIR}"
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+ CU_ACTION="Importing CRL (ML-DSA-87) for groups 1"
|
|
+ crlu -D -n TestCA-ml-dsa-87 -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
+ crlu -I -i ${CRL_FILE}-ml-dsa-87 -n "TestCA-ml-dsa-87" -f "${R_PWFILE}" \
|
|
+ -d "${R_SERVERDIR}"
|
|
+ CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
+fi
|
|
+
|
|
CU_ACTION="Importing CRL (ECC) for groups 1"
|
|
crlu -D -n TestCA-ec -f "${R_PWFILE}" -d "${R_SERVERDIR}"
|
|
crlu -I -i ${CRL_FILE}-ec -n "TestCA-ec" -f "${R_PWFILE}" \
|
|
-d "${R_SERVERDIR}"
|
|
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
|
|
|
|
if [ "$CERTFAILED" != 0 -o "$CRL_GEN_RES" != 0 ] ; then
|
|
cert_log "ERROR: SSL CRL prep failed $CERTFAILED : $CRL_GEN_RES"
|
|
diff --git a/tests/common/certsetup.sh b/tests/common/certsetup.sh
|
|
--- a/tests/common/certsetup.sh
|
|
+++ b/tests/common/certsetup.sh
|
|
@@ -32,25 +32,49 @@ make_cert() {
|
|
dsa) type_args=(-g 1024) ;;
|
|
rsa) type_args=(-g 1024) ;;
|
|
rsa2048) type_args=(-g 2048);type=rsa ;;
|
|
rsa8192) type_args=(-g 8192);type=rsa ;;
|
|
rsapss) type_args=(-g 1024 --pss);type=rsa ;;
|
|
rsapss384) type_args=(-g 1024 --pss);type=rsa;sighash=(-Z SHA384) ;;
|
|
rsapss512) type_args=(-g 2048 --pss);type=rsa;sighash=(-Z SHA512) ;;
|
|
rsapss_noparam) type_args=(-g 2048 --pss);type=rsa;sighash=() ;;
|
|
+ mldsa44) type_args=(-q ml-dsa-44);type=mldsa;sighash=() ;;
|
|
+ mldsa65) type_args=(-q ml-dsa-65);type=mldsa;sighash=() ;;
|
|
+ mldsa87) type_args=(-q ml-dsa-87);type=mldsa;sighash=() ;;
|
|
p256) type_args=(-q nistp256);type=ec ;;
|
|
p384) type_args=(-q secp384r1);type=ec ;;
|
|
p521) type_args=(-q secp521r1);type=ec ;;
|
|
rsa_ca) type_args=(-g 1024);trust='CT,CT,CT';type=rsa ;;
|
|
+ mldsa44_ca) type_args=(-q ml-dsa-44);trust='CT,CT,CT';type=mldsa ;;
|
|
+ mldsa65_ca) type_args=(-q ml-dsa-65);trust='CT,CT,CT';type=mldsa ;;
|
|
+ mldsa87_ca) type_args=(-q ml-dsa-87);trust='CT,CT,CT';type=mldsa ;;
|
|
rsa_chain) type_args=(-g 1024);sign=(-c rsa_ca);type=rsa;;
|
|
rsapss_ca) type_args=(-g 1024 --pss);trust='CT,CT,CT';type=rsa ;;
|
|
rsapss_chain) type_args=(-g 1024);sign=(-c rsa_pss_ca);type=rsa;;
|
|
rsa_ca_rsapss_chain) type_args=(-g 1024 --pss-sign);sign=(-c rsa_ca);type=rsa;;
|
|
+ mldsa44_chain) type_args=(-q ml-dsa-44);sign=(-c mldsa44_ca);type=mldsa;;
|
|
+ mldsa65_chain) type_args=(-q ml-dsa-65);sign=(-c mldsa65_ca);type=mldsa;;
|
|
+ mldsa87_chain) type_args=(-q ml-dsa-87);sign=(-c mldsa87_ca);type=mldsa;;
|
|
ecdh_rsa) type_args=(-q nistp256);sign=(-c rsa_ca);type=ec ;;
|
|
+ delegator_mldsa44)
|
|
+ touch empty.txt
|
|
+ type_args=(-q ml-dsa-44 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
|
+ type=mldsa
|
|
+ ;;
|
|
+ delegator_mldsa65)
|
|
+ touch empty.txt
|
|
+ type_args=(-q ml-dsa-65 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
|
+ type=mldsa
|
|
+ ;;
|
|
+ delegator_mldsa87)
|
|
+ touch empty.txt
|
|
+ type_args=(-q ml-dsa-87 --extGeneric 1.3.6.1.4.1.87363.87:not-critical:empty.txt)
|
|
+ type=mldsa
|
|
+ ;;
|
|
delegator_p256)
|
|
touch empty.txt
|
|
type_args=(-q nistp256 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
|
type=ec
|
|
;;
|
|
delegator_rsae2048)
|
|
touch empty.txt
|
|
type_args=(-g 2048 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
|
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
|
--- a/tests/ssl/ssl.sh
|
|
+++ b/tests/ssl/ssl.sh
|
|
@@ -241,45 +241,54 @@ kill_selfserv()
|
|
# also: wait until the server is up and running
|
|
########################################################################
|
|
start_selfserv()
|
|
{
|
|
if [ -n "$testname" ] ; then
|
|
echo "$SCRIPTNAME: $testname ----"
|
|
fi
|
|
if [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1" ] ; then
|
|
- ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec"
|
|
+ ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec "
|
|
else
|
|
ECC_OPTIONS=""
|
|
fi
|
|
if [ -z "$RSA_PSS_CERT" -o "$RSA_PSS_CERT" != "1" ] ; then
|
|
RSA_OPTIONS="-n ${HOSTADDR}"
|
|
else
|
|
RSA_OPTIONS="-n ${HOSTADDR}-rsa-pss"
|
|
fi
|
|
if [ -z "$NSS_DISABLE_DSA" ]; then
|
|
- DSA_OPTIONS="-S ${HOSTADDR}-dsa"
|
|
+ DSA_OPTIONS="-S ${HOSTADDR}-dsa "
|
|
else
|
|
DSA_OPTIONS=""
|
|
fi
|
|
+ # There are no differences any more between -e, and -S. They both do
|
|
+ # exactly the same thing. SSL looks at the certificate itself and decides
|
|
+ # how to use it. The -n is expecting a single value, using it here will mess
|
|
+ # up SNI test. So use -e as the most generic.
|
|
+ if [ -n "$NSS_ENABLE_ML_DSA" ]; then
|
|
+ ML_DSA_OPTIONS="-e ${HOSTADDR}-ml-dsa-44 -e ${HOSTADDR}-ml-dsa-65 -e ${HOSTADDR}-ml-dsa-87 "
|
|
+ else
|
|
+ ML_DSA_OPTIONS=""
|
|
+ fi
|
|
|
|
SERVER_VMIN=${SERVER_VMIN-ssl3}
|
|
SERVER_VMAX=${SERVER_VMAX-tls1.2}
|
|
echo "selfserv starting at `date`"
|
|
echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \\"
|
|
- echo " ${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID}\\"
|
|
+ echo " ${ECC_OPTIONS}${DSA_OPTIONS}${ML_DSA_OPTIONS}-w nss "$@" -i ${R_SERVERPID}\\"
|
|
echo " -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &"
|
|
if [ ${fileout} -eq 1 ]; then
|
|
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
|
|
- ${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 \
|
|
+ ${ECC_OPTIONS}${DSA_OPTIONS}${ML_DSA_OPTIONS}-w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 \
|
|
> ${SERVEROUTFILE} 2>&1 &
|
|
RET=$?
|
|
else
|
|
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
|
|
- ${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &
|
|
+ ${ECC_OPTIONS}${DSA_OPTIONS}${ML_DSA_OPTIONS}-w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &
|
|
RET=$?
|
|
fi
|
|
|
|
# The PID $! returned by the MKS or Cygwin shell is not the PID of
|
|
# the real background process, but rather the PID of a helper
|
|
# process (sh.exe). MKS's kill command has a bug: invoking kill
|
|
# on the helper process does not terminate the real background
|
|
# process. Our workaround has been to have selfserv save its PID
|
|
@@ -377,30 +386,36 @@ ssl_cov()
|
|
# restart it to enable ssl3
|
|
if [ "$VMAX" = "ssl3" -a "$VMIN" = "tls1.1" ]; then
|
|
kill_selfserv
|
|
start_selfserv $CIPHER_SUITES
|
|
VMIN="ssl3"
|
|
fi
|
|
|
|
TLS_GROUPS=${CLIENT_GROUPS}
|
|
+ TLS_SIG_SCHEMES=""
|
|
if [ "$ectype" = "MLKEM256" ]; then
|
|
TLS_GROUPS="secp256r1mlkem768"
|
|
+ TLS_SIG_SCHEMES="-J mldsa65"
|
|
elif [ "$ectype" = "MLKEM219" ]; then
|
|
TLS_GROUPS="x25519mlkem768"
|
|
+ TLS_SIG_SCHEMES="-J mldsa44"
|
|
elif [ "$ectype" = "MLKEM384" ]; then
|
|
TLS_GROUPS="secp384r1mlkem1024"
|
|
+ TLS_SIG_SCHEMES="-J mldsa87"
|
|
+ elif [ "$ectype" = "MLDSAECC" ]; then
|
|
+ TLS_SIG_SCHEMES="-J mldsa44"
|
|
fi
|
|
echo "TLS_GROUPS=${TLS_GROUPS}"
|
|
|
|
- echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
|
|
+ echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" ${TLS_SIG_SCHEMES} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
|
|
echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
|
|
|
|
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
|
- ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
|
|
+ ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" ${TLS_SIG_SCHEMES} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
|
|
-d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
|
|
>${TMP}/$HOST.tmp.$$ 2>&1
|
|
ret=$?
|
|
cat ${TMP}/$HOST.tmp.$$
|
|
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
|
html_msg $ret 0 "${testname}" \
|
|
"produced a returncode of $ret, expected is 0"
|
|
done < ${SSL_COV_TMP}
|
|
@@ -693,16 +708,22 @@ ssl_stress()
|
|
if [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then
|
|
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
|
|
elif [ "${CLIENT_MODE}" = "fips" -a "${CAUTH}" -ne 0 ] ; then
|
|
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
|
|
elif [ "${NOLOGIN}" -eq 0 ] && \
|
|
[ "${CLIENT_MODE}" = "fips" -o "$NORM_EXT" = "Extended Test" ] ; then
|
|
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
|
|
else
|
|
+ unset SERVER_VMIN
|
|
+ unset SERVER_VMAX
|
|
+ if [ "$ectype" = "MLDSA" ]; then
|
|
+ SERVER_VMIN="tls1.1"
|
|
+ SERVER_VMAX="tls1.3"
|
|
+ fi
|
|
cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
|
|
if [ "$ectype" = "SNI" ]; then
|
|
cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
|
|
sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
|
|
fi
|
|
|
|
start_selfserv `echo "$sparam" | sed -e 's,_, ,g'`
|
|
|
|
@@ -713,20 +734,20 @@ ssl_stress()
|
|
|
|
if [ "${NOLOGIN}" -eq 0 ] ; then
|
|
dbdir=${P_R_NOLOGINDIR}
|
|
else
|
|
dbdir=${P_R_CLIENTDIR}
|
|
fi
|
|
|
|
echo "strsclnt -4 -q -p ${PORT} -d ${dbdir} ${CLIENT_OPTIONS} -w nss $cparam \\"
|
|
- echo " -V ssl3:tls1.2 $verbose ${HOSTADDR}"
|
|
+ echo " $verbose ${HOSTADDR}"
|
|
echo "strsclnt started at `date`"
|
|
${PROFTOOL} ${BINDIR}/strsclnt -4 -q -p ${PORT} -d ${dbdir} ${CLIENT_OPTIONS} -w nss $cparam \
|
|
- -V ssl3:tls1.2 $verbose ${HOSTADDR}
|
|
+ $verbose ${HOSTADDR}
|
|
ret=$?
|
|
echo "strsclnt completed at `date`"
|
|
html_msg $ret $value \
|
|
"${testname}" \
|
|
"produced a returncode of $ret, expected is $value. "
|
|
if [ "`uname -n`" = "sjsu" ] ; then
|
|
echo "debugging disapering selfserv... ps -ef | grep selfserv"
|
|
ps -ef | grep selfserv
|
|
@@ -1053,17 +1074,17 @@ ssl_policy_selfserv()
|
|
setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_SERVERDIR}
|
|
|
|
SAVE_SERVER_OPTIONS=${SERVER_OPTIONS}
|
|
# make sure policy is working in the multiprocess case is working on
|
|
# UNIX-like OS's. Other OS's can't properly clean up the child processes
|
|
# when our test suite kills the parent, so just use the single process
|
|
# self serve for them
|
|
# if [ "${OS_ARCH}" != "WINNT" ]; then
|
|
- # SERVER_OPTIONS="-M 3 ${SERVER_OPTIONS}"
|
|
+ SERVER_OPTIONS="-M 3 ${SERVER_OPTIONS}"
|
|
# fi
|
|
|
|
start_selfserv $CIPHER_SUITES
|
|
|
|
SERVER_OPTIONS="${SAVE_SERVER_OPTIONS}"
|
|
VMIN="ssl3"
|
|
VMAX="tls1.2"
|
|
|
|
@@ -1644,20 +1665,20 @@ ssl_run_tests()
|
|
ssl_iopr_run
|
|
;;
|
|
*)
|
|
SERVER_MODE=`echo "${SSL_TEST}" | cut -d_ -f1`
|
|
CLIENT_MODE=`echo "${SSL_TEST}" | cut -d_ -f2`
|
|
|
|
case "${SERVER_MODE}" in
|
|
"normal")
|
|
- SERVER_OPTIONS=
|
|
+ SERVER_OPTIONS=""
|
|
;;
|
|
"fips")
|
|
- SERVER_OPTIONS=
|
|
+ SERVER_OPTIONS=""
|
|
ssl_set_fips server on
|
|
;;
|
|
*)
|
|
html_failed "${SCRIPTNAME}: Error: Unknown server mode ${SERVER_MODE}"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
diff --git a/tests/ssl/sslauth.txt b/tests/ssl/sslauth.txt
|
|
--- a/tests/ssl/sslauth.txt
|
|
+++ b/tests/ssl/sslauth.txt
|
|
@@ -77,8 +77,27 @@
|
|
SNI 1 -r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni1.Dom TLS Server response with alert
|
|
SNI 0 -r_-a_Host-sni.Dom -V_ssl3:ssl3_-w_nss_-n_TestUser SSL3 Server hello response without SNI
|
|
SNI 1 -r_-a_Host-sni.Dom -V_ssl3:ssl3_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom SSL3 Server hello response with SNI: SSL don't have SH extensions
|
|
SNI 0 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-w_nss_-n_TestUser TLS Server hello response without SNI
|
|
SNI 0 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom TLS Server hello response with SNI
|
|
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-w_nss_-n_TestUser_-a_Host-sni.Dom_-a_Host.Dom TLS Server hello response with SNI: Change name on 2d HS
|
|
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom_-a_Host-sni1.Dom TLS Server hello response with SNI: Change name to invalid 2d HS
|
|
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni1.Dom TLS Server response with alert
|
|
+
|
|
+#
|
|
+# ML-DSA Tests
|
|
+#
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client does not provide auth)
|
|
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client does not provide auth)
|
|
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs with session ticket (client auth)
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs (client does not provide auth)
|
|
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-65 Require client auth on post hs (client does not provide auth)
|
|
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs with session ticket (client auth)
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client auth)
|
|
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client does not provide auth)
|
|
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client does not provide auth)
|
|
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs with session ticket (client auth)
|
|
diff --git a/tests/ssl/sslcov.txt b/tests/ssl/sslcov.txt
|
|
--- a/tests/ssl/sslcov.txt
|
|
+++ b/tests/ssl/sslcov.txt
|
|
@@ -151,8 +151,9 @@ MLKEM384 TLS13 :1301 TLS13_MLKEM1024P38
|
|
MLKEM384 TLS13 :1302 TLS13_MLKEM1024P384_WITH_AES_256_GCM_SHA384
|
|
MLKEM384 TLS13 :1303 TLS13_MLKEM1024P384_WITH_CHACHA20_POLY1305_SHA256
|
|
MLKEM256 TLS13 :1301 TLS13_MLKEM768P256_WITH_AES_128_GCM_SHA256
|
|
MLKEM256 TLS13 :1302 TLS13_MLKEM768P256_WITH_AES_256_GCM_SHA384
|
|
MLKEM256 TLS13 :1303 TLS13_MLKEM768P256_WITH_CHACHA20_POLY1305_SHA256
|
|
MLKEM219 TLS13 :1301 TLS13_MLKEM768X25519_WITH_AES_128_GCM_SHA256
|
|
MLKEM219 TLS13 :1302 TLS13_MLKEM768X25519_WITH_AES_256_GCM_SHA384
|
|
MLKEM219 TLS13 :1303 TLS13_MLKEM768X25519_WITH_CHACHA20_POLY1305_SHA256
|
|
+MLDSAECC TLS13 :1301 TLS13_ECDHE_WITH_AES_128_GCM_SHA256_WITH_MLDSA44
|
|
diff --git a/tests/ssl_gtests/ssl_gtests.sh b/tests/ssl_gtests/ssl_gtests.sh
|
|
--- a/tests/ssl_gtests/ssl_gtests.sh
|
|
+++ b/tests/ssl_gtests/ssl_gtests.sh
|
|
@@ -54,16 +54,30 @@ ssl_gtest_certs() {
|
|
make_cert rsa_chain rsa_chain sign
|
|
make_cert rsa_pss_ca rsapss_ca ca
|
|
make_cert rsa_pss_chain rsapss_chain sign
|
|
make_cert rsa_ca_rsa_pss_chain rsa_ca_rsapss_chain sign
|
|
make_cert ecdh_rsa ecdh_rsa kex
|
|
if [ -z "${NSS_DISABLE_DSA}" ]; then
|
|
make_cert dsa dsa sign
|
|
fi
|
|
+ if [ -n "${NSS_ENABLE_ML_DSA}" ]; then
|
|
+ make_cert mldsa44 mldsa44 sign
|
|
+ make_cert mldsa44_ca mldsa44_ca ca
|
|
+ make_cert mldsa44_chain mldsa44_chain sign
|
|
+ make_cert delegator_mldsa44 delegator_mldsa44 sign
|
|
+ make_cert mldsa65 mldsa65 sign
|
|
+ make_cert mldsa65_ca mldsa65_ca ca
|
|
+ make_cert mldsa65_chain mldsa65_chain sign
|
|
+ make_cert delegator_mldsa65 delegator_mldsa65 sign
|
|
+ make_cert mldsa87 mldsa87 sign
|
|
+ make_cert mldsa87_ca mldsa87_ca ca
|
|
+ make_cert mldsa87_chain mldsa87_chain sign
|
|
+ make_cert delegator_mldsa87 delegator_mldsa87 sign
|
|
+ fi
|
|
make_cert delegator_ecdsa256 delegator_p256 sign
|
|
make_cert delegator_rsae2048 delegator_rsae2048 sign
|
|
make_cert delegator_rsa_pss2048 delegator_rsa_pss2048 sign
|
|
}
|
|
|
|
############################## ssl_gtest_init ##########################
|
|
# local shell function to initialize this script
|
|
########################################################################
|