Merge pull request #4062 from dgarske/dh_key

DH Key and Params Export cleanups and Apache httpd fixes
This commit is contained in:
Sean Parkinson
2021-06-10 20:54:32 +10:00
committed by GitHub
15 changed files with 351 additions and 382 deletions

273
src/ssl.c
View File

@@ -45724,274 +45724,7 @@ end:
}
#endif /* !NO_BIO */
#ifndef NO_FILESYSTEM
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
/* Convert DH key parameters to DER format, write to output (outSz)
* If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
* returned.
*
* Note : static function due to redefinition complications with DhKey and FIPS
* version 2 build.
*
* return bytes written on success */
int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz)
{
word32 sz = 0, idx = 0;
int pSz = 0, gSz = 0, ret;
byte scratch[MAX_LENGTH_SZ];
if (key == NULL || outSz == NULL) {
return BAD_FUNC_ARG;
}
pSz = mp_unsigned_bin_size(&key->p);
if (pSz < 0) {
return pSz;
}
if (mp_leading_bit(&key->p)) {
pSz++;
}
gSz = mp_unsigned_bin_size(&key->g);
if (gSz < 0) {
return gSz;
}
if (mp_leading_bit(&key->g)) {
gSz++;
}
sz = ASN_TAG_SZ; /* Integer */
sz += SetLength(pSz, scratch);
sz += ASN_TAG_SZ; /* Integer */
sz += SetLength(gSz, scratch);
sz += gSz + pSz;
if (out == NULL) {
byte seqScratch[MAX_SEQ_SZ];
*outSz = sz + SetSequence(sz, seqScratch);
return LENGTH_ONLY_E;
}
if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
return BUFFER_E;
}
idx += SetSequence(sz, out);
if (*outSz < idx + sz) {
return BUFFER_E;
}
out[idx++] = ASN_INTEGER;
idx += SetLength(pSz, out + idx);
if (mp_leading_bit(&key->p)) {
out[idx++] = 0x00;
pSz -= 1; /* subtract 1 from size to account for leading 0 */
}
ret = mp_to_unsigned_bin(&key->p, out + idx);
if (ret != MP_OKAY) {
return BUFFER_E;
}
idx += pSz;
out[idx++] = ASN_INTEGER;
idx += SetLength(gSz, out + idx);
if (mp_leading_bit(&key->g)) {
out[idx++] = 0x00;
gSz -= 1; /* subtract 1 from size to account for leading 0 */
}
ret = mp_to_unsigned_bin(&key->g, out + idx);
if (ret != MP_OKAY) {
return BUFFER_E;
}
idx += gSz;
return idx;
}
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz)
{
word32 sz = 0;
word32 paramSz = 0;
int ret;
int pubSz = 0;
int idx = 0;
byte scratch[MAX_ALGO_SZ];
/* Get size of entire key */
/* SEQUENCE <--| SetAlgoId
* OBJECT IDENTIFIER <--|
* SEQUENCE <--
* INTEGER | wc_DhParamsToDer
* INTEGER <--
*/
ret = wc_DhParamsToDer(key, NULL, &paramSz);
if (ret != LENGTH_ONLY_E)
return ASN_PARSE_E;
sz += paramSz;
sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz);
/* BIT STRING
* INTEGER
*/
pubSz = mp_unsigned_bin_size(&key->pub);
if (pubSz < 0)
return pubSz;
if (mp_leading_bit(&key->pub))
pubSz++;
sz += ASN_TAG_SZ; /* Integer */
sz += SetLength(pubSz, scratch);
sz += pubSz;
sz += SetBitString(pubSz, 0, scratch);
if (out == NULL) {
/* Uppermost SEQUENCE */
*outSz = sz + SetSequence(sz, scratch);
return LENGTH_ONLY_E;
}
/* end get size of entire key */
/* Check for indexing errors */
if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
return BUFFER_E;
}
/* Build Up Entire Key */
idx += SetSequence(sz, out);
idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz);
ret = wc_DhParamsToDer(key, out+idx, &paramSz);
if (ret < 0)
return ret;
idx += ret;
/* BIT STRING
* INTEGER
*/
idx += SetBitString(pubSz, 0, out+idx);
out[idx++] = ASN_INTEGER;
idx += SetLength(pubSz, out + idx);
if (mp_leading_bit(&key->pub)) {
out[idx++] = 0x00;
pubSz -= 1; /* subtract 1 from size to account for leading 0 */
}
ret = mp_to_unsigned_bin(&key->pub, out + idx);
if (ret != MP_OKAY) {
return BUFFER_E;
}
idx += pubSz;
return idx;
}
int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
{
word32 sz = 0;
word32 paramSz = 0;
int ret;
int privSz = 0;
int idx = 0;
byte scratch[MAX_ALGO_SZ];
/* Get size of entire key */
/* INTEGER 0 */
sz += ASN_TAG_SZ; /* Integer */
sz += SetLength(1, scratch);
sz += 1;
/* SEQUENCE <--| SetAlgoId
* OBJECT IDENTIFIER <--|
* SEQUENCE <--
* INTEGER | wc_DhParamsToDer
* INTEGER <--
*/
ret = wc_DhParamsToDer(key, NULL, &paramSz);
if (ret != LENGTH_ONLY_E)
return ASN_PARSE_E;
sz += paramSz;
sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz);
/* OCTET STRING
* INTEGER
*/
privSz = mp_unsigned_bin_size(&key->priv);
if (privSz < 0)
return privSz;
else if (privSz > 256) /* Key is larger than 2048 */
return ASN_VERSION_E;
if (mp_leading_bit(&key->priv))
privSz++;
sz += ASN_TAG_SZ; /* Integer */
sz += SetLength(privSz, scratch);
sz += privSz;
sz += SetOctetString(privSz + ASN_OCTET_STRING, scratch);
if (out == NULL) {
/* Uppermost SEQUENCE */
*outSz = sz + SetSequence(sz, scratch);
return LENGTH_ONLY_E;
}
/* end get size of entire key */
/* Check for indexing errors */
if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
return BUFFER_E;
}
/* Build Up Entire Key */
idx += SetSequence(sz, out);
/* INTEGER 0 */
out[idx++] = ASN_INTEGER;
idx += SetLength(1, out+idx);
out[idx++] = 0;
idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz);
ret = wc_DhParamsToDer(key, out+idx, &paramSz);
if (ret < 0)
return ret;
idx += ret;
/* OCTET STRING
* INTEGER
*/
if (privSz == 256) {
idx += SetOctetString(privSz + ASN_OCTET_STRING, out+idx);
} else if (privSz == 128) {
idx += SetOctetString(privSz + ASN_OCTET_STRING-1, out+idx);
} else if (privSz == 64) {
idx += SetOctetString(privSz + ASN_OCTET_STRING-2, out+idx);
} else {
WOLFSSL_MSG("Unsupported key size");
return ASN_VERSION_E;
}
out[idx++] = ASN_INTEGER;
idx += SetLength(privSz, out + idx);
if (mp_leading_bit(&key->priv)) {
out[idx++] = 0x00;
privSz -= 1; /* subtract 1 from size to account for leading 0 */
}
ret = mp_to_unsigned_bin(&key->priv, out + idx);
if (ret != MP_OKAY) {
return BUFFER_E;
}
idx += privSz;
return idx;
}
#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
/* Writes the DH parameters in PEM format from "dh" out to the file pointer
* passed in.
*
@@ -46074,9 +45807,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", WOLFSSL_SUCCESS);
return WOLFSSL_SUCCESS;
}
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* WOLFSSL_QT || OPENSSL_ALL */
#endif /* !NO_FILESYSTEM */
#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
#endif /* !NO_DH */
#ifndef NO_BIO