forked from wolfSSL/wolfssl
Merge pull request #2307 from SparkiDev/pick_hash_sig
Improve hash and signature algorithm selection
This commit is contained in:
@ -2013,6 +2013,13 @@ static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo, byte sig
|
||||
*inOutIdx += 1;
|
||||
suites->hashSigAlgo[*inOutIdx] = macAlgo;
|
||||
*inOutIdx += 1;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
/* Add the certificate algorithm as well */
|
||||
suites->hashSigAlgo[*inOutIdx] = sigAlgo;
|
||||
*inOutIdx += 1;
|
||||
suites->hashSigAlgo[*inOutIdx] = PSS_RSAE_TO_PSS_PSS(macAlgo);
|
||||
*inOutIdx += 1;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
suites->hashSigAlgo[*inOutIdx] = macAlgo;
|
||||
@ -2986,7 +2993,8 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
|
||||
|
||||
suites->suiteSz = idx;
|
||||
|
||||
InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0, tls1_2, keySz);
|
||||
InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC, haveRSAsig | haveRSA,
|
||||
0, tls1_2, keySz);
|
||||
}
|
||||
|
||||
#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) || \
|
||||
@ -3002,13 +3010,6 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy
|
||||
{
|
||||
switch (input[0]) {
|
||||
case NEW_SA_MAJOR:
|
||||
#ifdef WC_RSA_PSS
|
||||
/* PSS signatures: 0x080[4-6] */
|
||||
if (input[1] <= sha512_mac) {
|
||||
*hsType = input[0];
|
||||
*hashAlgo = input[1];
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
/* ED25519: 0x0807 */
|
||||
if (input[1] == ED25519_SA_MINOR) {
|
||||
@ -3016,8 +3017,21 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy
|
||||
/* Hash performed as part of sign/verify operation. */
|
||||
*hashAlgo = sha512_mac;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WC_RSA_PSS
|
||||
/* PSS PSS signatures: 0x080[9-b] */
|
||||
if (input[1] >= pss_sha256 && input[1] <= pss_sha512) {
|
||||
*hsType = rsa_pss_pss_algo;
|
||||
*hashAlgo = PSS_PSS_HASH_TO_MAC(input[1]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* ED448: 0x0808 */
|
||||
{
|
||||
*hsType = input[0];
|
||||
*hashAlgo = input[1];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*hashAlgo = input[0];
|
||||
@ -16926,10 +16940,10 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
|
||||
|
||||
|
||||
#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)
|
||||
void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
word32 hashSigAlgoSz)
|
||||
int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
|
||||
{
|
||||
word32 i;
|
||||
int ret = MATCH_SUITE_ERROR;
|
||||
|
||||
ssl->suites->sigAlgo = ssl->specs.sig_algo;
|
||||
|
||||
@ -16953,6 +16967,9 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hashSigAlgoSz == 0)
|
||||
return 0;
|
||||
|
||||
/* i+1 since peek a byte ahead for type */
|
||||
for (i = 0; (i+1) < hashSigAlgoSz; i += HELLO_EXT_SIGALGO_SZ) {
|
||||
byte hashAlgo = 0, sigAlgo = 0;
|
||||
@ -16966,6 +16983,7 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
|
||||
ssl->suites->sigAlgo = sigAlgo;
|
||||
ssl->suites->hashAlgo = sha512_mac;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -16985,7 +17003,8 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
if (digestSz == ssl->eccTempKeySz) {
|
||||
ssl->suites->hashAlgo = hashAlgo;
|
||||
ssl->suites->sigAlgo = sigAlgo;
|
||||
return; /* done selected sig/hash algorithms */
|
||||
ret = 0;
|
||||
break; /* done selected sig/hash algorithms */
|
||||
}
|
||||
/* not strong enough, so keep checking hashSigAlso list */
|
||||
if (digestSz < ssl->eccTempKeySz)
|
||||
@ -16994,6 +17013,7 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
/* mark as highest and check remainder of hashSigAlgo list */
|
||||
ssl->suites->hashAlgo = hashAlgo;
|
||||
ssl->suites->sigAlgo = sigAlgo;
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -17015,8 +17035,10 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
case sha512_mac:
|
||||
#endif
|
||||
/* not strong enough, so keep checking hashSigAlso list */
|
||||
if (hashAlgo < ssl->suites->hashAlgo)
|
||||
if (hashAlgo < ssl->suites->hashAlgo) {
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
/* mark as highest and check remainder of hashSigAlgo list */
|
||||
ssl->suites->hashAlgo = hashAlgo;
|
||||
ssl->suites->sigAlgo = sigAlgo;
|
||||
@ -17024,12 +17046,16 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
else if (ssl->specs.sig_algo == 0) {
|
||||
else if (ssl->specs.sig_algo == 0 && !IsAtLeastTLSv1_3(ssl->version)) {
|
||||
ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) */
|
||||
|
||||
@ -18243,7 +18269,19 @@ exit_dpk:
|
||||
if ((*inOutIdx - begin) + len > size)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
PickHashSigAlgo(ssl, input + *inOutIdx, len);
|
||||
if (PickHashSigAlgo(ssl, input + *inOutIdx, len) != 0 &&
|
||||
ssl->buffers.certificate &&
|
||||
ssl->buffers.certificate->buffer) {
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
|
||||
WOLFSSL_MSG("Using PK for client private key");
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif
|
||||
if (ssl->buffers.key && ssl->buffers.key->buffer) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
*inOutIdx += len;
|
||||
#ifdef WC_RSA_PSS
|
||||
ssl->pssAlgo = 0;
|
||||
@ -23438,9 +23476,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ssl->options.cipherSuite0 = ssl->suites->suites[i];
|
||||
ssl->options.cipherSuite = ssl->suites->suites[i+1];
|
||||
result = SetCipherSpecs(ssl);
|
||||
if (result == 0)
|
||||
PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
|
||||
if (result == 0) {
|
||||
result = PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
|
||||
peerSuites->hashSigAlgoSz);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
|
17
src/tls13.c
17
src/tls13.c
@ -3233,7 +3233,11 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
|
||||
*inOutIdx += OPAQUE16_LEN;
|
||||
if ((*inOutIdx - begin) + len > size)
|
||||
return BUFFER_ERROR;
|
||||
PickHashSigAlgo(ssl, input + *inOutIdx, len);
|
||||
if (PickHashSigAlgo(ssl, input + *inOutIdx, len) != 0 &&
|
||||
ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
|
||||
ssl->buffers.key && ssl->buffers.key->buffer) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
*inOutIdx += len;
|
||||
|
||||
/* Length of certificate authority data. */
|
||||
@ -3287,13 +3291,18 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
|
||||
return ret;
|
||||
}
|
||||
*inOutIdx += len;
|
||||
|
||||
PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, peerSuites.hashSigAlgoSz);
|
||||
#endif
|
||||
|
||||
if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
|
||||
ssl->buffers.key && ssl->buffers.key->buffer)
|
||||
ssl->buffers.key && ssl->buffers.key->buffer) {
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if (PickHashSigAlgo(ssl, peerSuites.hashSigAlgo,
|
||||
peerSuites.hashSigAlgoSz) != 0) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif
|
||||
ssl->options.sendVerify = SEND_CERT;
|
||||
}
|
||||
else
|
||||
ssl->options.sendVerify = SEND_BLANK_CERT;
|
||||
|
||||
|
@ -1652,7 +1652,7 @@ WOLFSSL_LOCAL int DoServerHello(WOLFSSL* ssl, const byte* input, word32*,
|
||||
word32);
|
||||
WOLFSSL_LOCAL int CompleteServerHello(WOLFSSL *ssl);
|
||||
WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv);
|
||||
WOLFSSL_LOCAL void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
WOLFSSL_LOCAL int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
word32 hashSigAlgoSz);
|
||||
WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length);
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
@ -2836,7 +2836,20 @@ enum SignatureAlgorithm {
|
||||
dsa_sa_algo = 2,
|
||||
ecc_dsa_sa_algo = 3,
|
||||
rsa_pss_sa_algo = 8,
|
||||
ed25519_sa_algo = 9
|
||||
ed25519_sa_algo = 9,
|
||||
rsa_pss_pss_algo = 10
|
||||
};
|
||||
|
||||
#define PSS_RSAE_TO_PSS_PSS(macAlgo) \
|
||||
(macAlgo + (pss_sha256 - sha256_mac))
|
||||
|
||||
#define PSS_PSS_HASH_TO_MAC(macAlgo) \
|
||||
(macAlgo - (pss_sha256 - sha256_mac))
|
||||
|
||||
enum SigAlgRsaPss {
|
||||
pss_sha256 = 0x09,
|
||||
pss_sha384 = 0x0a,
|
||||
pss_sha512 = 0x0b,
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user