openssl/providers/common/der/der_rsa_key.c
Richard Levitte a30027b680 Refactor the provider side DER constants and writers
This splits up all the providers/common/der/*.c.in so the generated
portion is on its own and all related DER writing routines are in
their own files.  This also ensures that the DIGEST consstants aren't
reproduced in several files (resulting in symbol clashes).

Finally, the production of OID macros is moved to the generated header
files, allowing other similar macros, or DER constant arrays, to be
built on top of them.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/11868)
2020-05-20 21:07:09 +02:00

375 lines
15 KiB
C

/*
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/obj_mac.h>
#include "internal/cryptlib.h"
#include "prov/der_rsa.h"
#include "prov/der_digests.h"
/* More complex pre-compiled sequences. TODO(3.0) refactor? */
/*-
* From https://tools.ietf.org/html/rfc8017#appendix-A.2.1
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
*/
#define DER_V_NULL DER_P_NULL, 0
#define DER_SZ_NULL 2
/*
* The names for the hash function AlgorithmIdentifiers are borrowed and
* expanded from https://tools.ietf.org/html/rfc4055#section-2.1
*
* sha1Identifier AlgorithmIdentifier ::= { id-sha1, NULL }
* sha224Identifier AlgorithmIdentifier ::= { id-sha224, NULL }
* sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL }
* sha384Identifier AlgorithmIdentifier ::= { id-sha384, NULL }
* sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL }
*/
/*
* NOTE: Some of the arrays aren't used other than inside sizeof(), which
* clang complains about (-Wno-unneeded-internal-declaration). To get
* around that, we make them non-static, and declare them an extra time to
* avoid compilers complaining about definitions without declarations.
*/
#if 0 /* Currently unused */
#define DER_AID_V_sha1Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha1 + DER_SZ_NULL, \
DER_OID_V_id_sha1, \
DER_V_NULL
extern const unsigned char der_aid_sha1Identifier[];
const unsigned char der_aid_sha1Identifier[] = {
DER_AID_V_sha1Identifier
};
#define DER_AID_SZ_sha1Identifier sizeof(der_aid_sha1Identifier)
#endif
#define DER_AID_V_sha224Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha224 + DER_SZ_NULL, \
DER_OID_V_id_sha224, \
DER_V_NULL
extern const unsigned char der_aid_sha224Identifier[];
const unsigned char der_aid_sha224Identifier[] = {
DER_AID_V_sha224Identifier
};
#define DER_AID_SZ_sha224Identifier sizeof(der_aid_sha224Identifier)
#define DER_AID_V_sha256Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha256 + DER_SZ_NULL, \
DER_OID_V_id_sha256, \
DER_V_NULL
extern const unsigned char der_aid_sha256Identifier[];
const unsigned char der_aid_sha256Identifier[] = {
DER_AID_V_sha256Identifier
};
#define DER_AID_SZ_sha256Identifier sizeof(der_aid_sha256Identifier)
#define DER_AID_V_sha384Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha384 + DER_SZ_NULL, \
DER_OID_V_id_sha384, \
DER_V_NULL
extern const unsigned char der_aid_sha384Identifier[];
const unsigned char der_aid_sha384Identifier[] = {
DER_AID_V_sha384Identifier
};
#define DER_AID_SZ_sha384Identifier sizeof(der_aid_sha384Identifier)
#define DER_AID_V_sha512Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha512 + DER_SZ_NULL, \
DER_OID_V_id_sha512, \
DER_V_NULL
extern const unsigned char der_aid_sha512Identifier[];
const unsigned char der_aid_sha512Identifier[] = {
DER_AID_V_sha512Identifier
};
#define DER_AID_SZ_sha512Identifier sizeof(der_aid_sha512Identifier)
#define DER_AID_V_sha512_224Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha512_224 + DER_SZ_NULL, \
DER_OID_V_id_sha512_224, \
DER_V_NULL
extern const unsigned char der_aid_sha512_224Identifier[];
const unsigned char der_aid_sha512_224Identifier[] = {
DER_AID_V_sha512_224Identifier
};
#define DER_AID_SZ_sha512_224Identifier sizeof(der_aid_sha512_224Identifier)
#define DER_AID_V_sha512_256Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_sha512_256 + DER_SZ_NULL, \
DER_OID_V_id_sha512_256, \
DER_V_NULL
extern const unsigned char der_aid_sha512_256Identifier[];
const unsigned char der_aid_sha512_256Identifier[] = {
DER_AID_V_sha512_256Identifier
};
#define DER_AID_SZ_sha512_256Identifier sizeof(der_aid_sha512_256Identifier)
/*-
* From https://tools.ietf.org/html/rfc8017#appendix-A.2.1
*
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
*
* ...
*
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
*/
/*
* The names for the MGF1 AlgorithmIdentifiers are borrowed and expanded
* from https://tools.ietf.org/html/rfc4055#section-2.1
*
* mgf1SHA1Identifier AlgorithmIdentifier ::=
* { id-mgf1, sha1Identifier }
* mgf1SHA224Identifier AlgorithmIdentifier ::=
* { id-mgf1, sha224Identifier }
* mgf1SHA256Identifier AlgorithmIdentifier ::=
* { id-mgf1, sha256Identifier }
* mgf1SHA384Identifier AlgorithmIdentifier ::=
* { id-mgf1, sha384Identifier }
* mgf1SHA512Identifier AlgorithmIdentifier ::=
* { id-mgf1, sha512Identifier }
*/
#if 0 /* Currently unused */
#define DER_AID_V_mgf1SHA1Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha1Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha1Identifier
static const unsigned char der_aid_mgf1SHA1Identifier[] = {
DER_AID_V_mgf1SHA1Identifier
};
#define DER_AID_SZ_mgf1SHA1Identifier sizeof(der_aid_mgf1SHA1Identifier)
#endif
#define DER_AID_V_mgf1SHA224Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha224Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha224Identifier
static const unsigned char der_aid_mgf1SHA224Identifier[] = {
DER_AID_V_mgf1SHA224Identifier
};
#define DER_AID_SZ_mgf1SHA224Identifier sizeof(der_aid_mgf1SHA224Identifier)
#define DER_AID_V_mgf1SHA256Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha256Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha256Identifier
static const unsigned char der_aid_mgf1SHA256Identifier[] = {
DER_AID_V_mgf1SHA256Identifier
};
#define DER_AID_SZ_mgf1SHA256Identifier sizeof(der_aid_mgf1SHA256Identifier)
#define DER_AID_V_mgf1SHA384Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha384Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha384Identifier
static const unsigned char der_aid_mgf1SHA384Identifier[] = {
DER_AID_V_mgf1SHA384Identifier
};
#define DER_AID_SZ_mgf1SHA384Identifier sizeof(der_aid_mgf1SHA384Identifier)
#define DER_AID_V_mgf1SHA512Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha512Identifier
static const unsigned char der_aid_mgf1SHA512Identifier[] = {
DER_AID_V_mgf1SHA512Identifier
};
#define DER_AID_SZ_mgf1SHA512Identifier sizeof(der_aid_mgf1SHA512Identifier)
#define DER_AID_V_mgf1SHA512_224Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_224Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha512_224Identifier
static const unsigned char der_aid_mgf1SHA512_224Identifier[] = {
DER_AID_V_mgf1SHA512_224Identifier
};
#define DER_AID_SZ_mgf1SHA512_224Identifier sizeof(der_aid_mgf1SHA512_224Identifier)
#define DER_AID_V_mgf1SHA512_256Identifier \
DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_256Identifier, \
DER_OID_V_id_mgf1, \
DER_AID_V_sha512_256Identifier
static const unsigned char der_aid_mgf1SHA512_256Identifier[] = {
DER_AID_V_mgf1SHA512_256Identifier
};
#define DER_AID_SZ_mgf1SHA512_256Identifier sizeof(der_aid_mgf1SHA512_256Identifier)
#define MGF1_SHA_CASE(bits, var) \
case NID_sha##bits: \
var = der_aid_mgf1SHA##bits##Identifier; \
var##_sz = sizeof(der_aid_mgf1SHA##bits##Identifier); \
break;
/*-
* The name is borrowed from https://tools.ietf.org/html/rfc8017#appendix-A.2.1
*
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
*/
static int DER_w_MaskGenAlgorithm(WPACKET *pkt, int tag,
const RSA_PSS_PARAMS_30 *pss)
{
if (pss != NULL && rsa_pss_params_30_maskgenalg(pss) == NID_mgf1) {
int maskgenhashalg_nid = rsa_pss_params_30_maskgenhashalg(pss);
const unsigned char *maskgenalg = NULL;
size_t maskgenalg_sz = 0;
switch (maskgenhashalg_nid) {
case NID_sha1:
break;
MGF1_SHA_CASE(224, maskgenalg);
MGF1_SHA_CASE(256, maskgenalg);
MGF1_SHA_CASE(384, maskgenalg);
MGF1_SHA_CASE(512, maskgenalg);
MGF1_SHA_CASE(512_224, maskgenalg);
MGF1_SHA_CASE(512_256, maskgenalg);
default:
return 0;
}
/* If there is none (or it was the default), we write nothing */
if (maskgenalg == NULL)
return 1;
return DER_w_precompiled(pkt, tag, maskgenalg, maskgenalg_sz);
}
return 0;
}
#define OAEP_PSS_MD_CASE(name, var) \
case NID_##name: \
var = der_oid_id_##name; \
var##_sz = sizeof(der_oid_id_##name); \
break;
int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss)
{
int hashalg_nid, default_hashalg_nid;
int saltlen, default_saltlen;
int trailerfield, default_trailerfield;
const unsigned char *hashalg = NULL;
size_t hashalg_sz = 0;
/*
* For an unrestricted key, this function should not have been called;
* the caller must be in control, because unrestricted keys are permitted
* in some situations (when encoding the public key in a SubjectKeyInfo,
* for example) while not in others, and this function doesn't know the
* intent. Therefore, we assert that here, the PSS parameters must show
* that the key is restricted.
*/
if (!ossl_assert(pss != NULL && !rsa_pss_params_30_is_unrestricted(pss)))
return 0;
hashalg_nid = rsa_pss_params_30_hashalg(pss);
saltlen = rsa_pss_params_30_saltlen(pss);
trailerfield = rsa_pss_params_30_trailerfield(pss);
/* Getting default values */
default_hashalg_nid = rsa_pss_params_30_hashalg(NULL);
default_saltlen = rsa_pss_params_30_saltlen(NULL);
default_trailerfield = rsa_pss_params_30_trailerfield(NULL);
/*
* From https://tools.ietf.org/html/rfc8017#appendix-A.2.1:
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
*/
switch (hashalg_nid) {
OAEP_PSS_MD_CASE(sha1, hashalg);
OAEP_PSS_MD_CASE(sha224, hashalg);
OAEP_PSS_MD_CASE(sha256, hashalg);
OAEP_PSS_MD_CASE(sha384, hashalg);
OAEP_PSS_MD_CASE(sha512, hashalg);
OAEP_PSS_MD_CASE(sha512_224, hashalg);
OAEP_PSS_MD_CASE(sha512_256, hashalg);
default:
return 0;
}
return DER_w_begin_sequence(pkt, tag)
&& (trailerfield == default_trailerfield
|| DER_w_ulong(pkt, 3, trailerfield))
&& (saltlen == default_saltlen || DER_w_ulong(pkt, 2, saltlen))
&& DER_w_MaskGenAlgorithm(pkt, 1, pss)
&& (hashalg_nid == default_hashalg_nid
|| DER_w_precompiled(pkt, 0, hashalg, hashalg_sz))
&& DER_w_end_sequence(pkt, tag);
}
/* Aliases so we can have a uniform RSA_CASE */
#define der_oid_rsassaPss der_oid_id_RSASSA_PSS
#define RSA_CASE(name, var) \
var##_nid = NID_##name; \
var##_oid = der_oid_##name; \
var##_oid_sz = sizeof(der_oid_##name); \
break;
int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa)
{
int rsa_nid = NID_undef;
const unsigned char *rsa_oid = NULL;
size_t rsa_oid_sz = 0;
RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa);
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
RSA_CASE(rsaEncryption, rsa);
case RSA_FLAG_TYPE_RSASSAPSS:
RSA_CASE(rsassaPss, rsa);
}
if (rsa_oid == NULL)
return 0;
return DER_w_begin_sequence(pkt, tag)
&& (rsa_nid != NID_rsassaPss
|| rsa_pss_params_30_is_unrestricted(pss_params)
|| DER_w_RSASSA_PSS_params(pkt, -1, pss_params))
&& DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz)
&& DER_w_end_sequence(pkt, tag);
}