VirtualBox

Changeset 100442 in vbox


Ignore:
Timestamp:
Jul 8, 2023 11:10:51 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158185
Message:

IPRT,OpenSSL: Support ECDSA for verficiation purposes when IPRT links with OpenSSL. This required quite a bit of cleanups, so not entirely no-risk. bugref:10479 ticketref:21621

Location:
trunk
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/crypto/key.h

    r98103 r100442  
    6666    /** RSA public key. */
    6767    RTCRKEYTYPE_RSA_PUBLIC,
     68    /** ECDSA private key. */
     69    RTCRKEYTYPE_ECDSA_PRIVATE,
     70    /** ECDSA public key. */
     71    RTCRKEYTYPE_ECDSA_PUBLIC,
    6872    /** End of key types. */
    6973    RTCRKEYTYPE_END,
     
    7579RTDECL(int)             RTCrKeyCreateFromSubjectPublicKeyInfo(PRTCRKEY phKey, struct RTCRX509SUBJECTPUBLICKEYINFO const *pSrc,
    7680                                                              PRTERRINFO pErrInfo, const char *pszErrorTag);
    77 RTDECL(int)             RTCrKeyCreateFromPublicAlgorithmAndBits(PRTCRKEY phKey,  PCRTASN1OBJID pAlgorithm,
    78                                                                 PCRTASN1BITSTRING pPublicKey,
     81RTDECL(int)             RTCrKeyCreateFromPublicAlgorithmAndBits(PRTCRKEY phKey, PCRTASN1OBJID pAlgorithm,
     82                                                                PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey,
    7983                                                                PRTERRINFO pErrInfo, const char *pszErrorTag);
    8084RTDECL(int)             RTCrKeyCreateFromPemSection(PRTCRKEY phKey, uint32_t fFlags, struct RTCRPEMSECTION const *pSection,
     
    105109RTDECL(int)             RTCrKeyQueryRsaModulus(RTCRKEY hKey, PRTBIGNUM pModulus);
    106110RTDECL(int)             RTCrKeyQueryRsaPrivateExponent(RTCRKEY hKey, PRTBIGNUM pPrivateExponent);
     111RTDECL(int)             RTCrKeyVerifyParameterCompatibility(RTCRKEY hKey, PCRTASN1DYNTYPE pParameters, bool fForSignature,
     112                                                            PCRTASN1OBJID pAlgorithm, PRTERRINFO pErrInfo);
     113
    107114
    108115/** Public key markers. */
  • trunk/include/iprt/crypto/pkix.h

    r98103 r100442  
    6060 * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
    6161 * @param   hPublicKey      The public key.
    62  * @param   pParameters     Parameter to the public key algorithm. Optional.
     62 * @param   pParameters     The signature parameters (not key, those are already
     63 *                          kept by hPublicKey).
    6364 * @param   pSignatureValue The signature value.
    6465 * @param   pvData          The signed data.
     
    8182 * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
    8283 * @param   hPublicKey      The public key.
    83  * @param   pParameters     Parameter to the public key algorithm. Optional.
     84 * @param   pParameters     The signature parameters (not key, those are already
     85 *                          kept by hPublicKey).
    8486 * @param   pvSignedDigest  The signed digest.
    8587 * @param   cbSignedDigest  The signed digest size.
     
    146148 *
    147149 * @returns Cipher OID string on success, NULL on failure.
    148  * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
     150 * @param   pAlgorithm          The signature algorithm (hash function w/ cipher).
     151 * @sa      RTCrX509AlgorithmIdentifier_GetEncryptionOid,
     152 *          RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid
    149153 */
    150154RTDECL(const char *) RTCrPkixGetCiperOidFromSignatureAlgorithm(PCRTASN1OBJID pAlgorithm);
     155
     156/**
     157 * Gets the cipher OID matching the given signature algorithm OID.
     158 *
     159 * @returns Cipher OID string on success, NULL on failure.
     160 * @param   pszSignatureOid     The signature algorithm ID (hash function w/ cipher).
     161 * @sa      RTCrX509AlgorithmIdentifier_GetEncryptionOid,
     162 *          RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid
     163 */
     164RTDECL(const char *) RTCrPkixGetCiperOidFromSignatureAlgorithmOid(const char *pszSignatureOid);
    151165
    152166
     
    170184#define RTCR_PKCS1_SHA512T224_WITH_RSA_OID          "1.2.840.113549.1.1.15"
    171185#define RTCR_PKCS1_SHA512T256_WITH_RSA_OID          "1.2.840.113549.1.1.16"
     186/** @} */
     187
     188/** @name ANSI X9.62 Object Identifiers (OIDs)
     189 * @{ */
     190#define RTCR_X962_ECDSA_OID                         "1.2.840.10045.2.1"
     191#define RTCR_X962_ECDSA_WITH_SHA1_OID               "1.2.840.10045.4.1"
     192#define RTCR_X962_ECDSA_WITH_SHA2_OID               "1.2.840.10045.4.3"
     193#define RTCR_X962_ECDSA_WITH_SHA224_OID             "1.2.840.10045.4.3.1"
     194#define RTCR_X962_ECDSA_WITH_SHA256_OID             "1.2.840.10045.4.3.2"
     195#define RTCR_X962_ECDSA_WITH_SHA384_OID             "1.2.840.10045.4.3.3"
     196#define RTCR_X962_ECDSA_WITH_SHA512_OID             "1.2.840.10045.4.3.4"
     197/** @}  */
     198
     199/** @name NIST Object Identifiers (OIDs)
     200 * @{ */
     201#define RTCR_NIST_ALGORITHM_OID                     "2.16.840.1.101.3.4"
     202#define RTCR_NIST_HASH_ALGS_OID                     "2.16.840.1.101.3.4.2"
     203#define RTCR_NIST_SIG_ALGS_OID                      "2.16.840.1.101.3.4.3"
     204#define RTCR_NIST_SHA3_224_WITH_ECDSA_OID           "2.16.840.1.101.3.4.3.9"
     205#define RTCR_NIST_SHA3_256_WITH_ECDSA_OID           "2.16.840.1.101.3.4.3.10"
     206#define RTCR_NIST_SHA3_384_WITH_ECDSA_OID           "2.16.840.1.101.3.4.3.11"
     207#define RTCR_NIST_SHA3_512_WITH_ECDSA_OID           "2.16.840.1.101.3.4.3.12"
     208#define RTCR_NIST_SHA3_224_WITH_RSA_OID             "2.16.840.1.101.3.4.3.13"
     209#define RTCR_NIST_SHA3_256_WITH_RSA_OID             "2.16.840.1.101.3.4.3.14"
     210#define RTCR_NIST_SHA3_384_WITH_RSA_OID             "2.16.840.1.101.3.4.3.15"
     211#define RTCR_NIST_SHA3_512_WITH_RSA_OID             "2.16.840.1.101.3.4.3.16"
    172212/** @}  */
    173213
     
    300340 * @param   ppvOpaque   Where to store an opaque schema parameter. Optional.
    301341 */
    302 PCRTCRPKIXSIGNATUREDESC RTCrPkixSignatureFindByObjIdString(const char *pszObjId, void *ppvOpaque);
     342PCRTCRPKIXSIGNATUREDESC RTCrPkixSignatureFindByObjIdString(const char *pszObjId, void **ppvOpaque);
    303343
    304344/**
  • trunk/include/iprt/crypto/x509.h

    r98103 r100442  
    8181 *
    8282 * @returns Valid RTDIGESTTYPE on success, RTDIGESTTYPE_INVALID on failure.
    83  * @param   pThis           The IPRT representation of a X.509 algorithm
    84  *                          identifier object.
    85  */
    86 RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_QueryDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis);
     83 * @param   pThis               The IPRT representation of a X.509 algorithm
     84 *                              identifier object.
     85 * @param   fPureDigestsOnly    Whether to only match IDs that only identify
     86 *                              digest algorithms, or whether to also include
     87 *                              IDs that mixes hash and encryption/whatever.
     88 */
     89RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_GetDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly);
    8790
    8891/**
     
    9093 *
    9194 * @returns The digest size in bytes, UINT32_MAX if unknown digest.
    92  * @param   pThis           The IPRT representation of a X.509 algorithm
    93  *                          identifier object.
    94  */
    95 RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_QueryDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis);
     95 * @param   pThis               The IPRT representation of a X.509 algorithm
     96 *                              identifier object.
     97 * @param   fPureDigestsOnly    Whether to only match IDs that only identify
     98 *                              digest algorithms, or whether to also include
     99 *                              IDs that mixes hash and encryption/whatever.
     100 */
     101RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_GetDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly);
     102
     103/**
     104 * Tries to get the encryption OID from the algorithm.
     105 *
     106 * @returns The encryption (cipher) OID  on success, NULL on failure.
     107 * @param   pThis               The IPRT representation of a X.509 algorithm
     108 *                              identifier object.
     109 * @param   fMustIncludeHash    Whether the algorithm ID represented by @a pThis
     110 *                              must include a hash (true) or whether it is
     111 *                              okay to accept pure encryption IDs as well
     112 *                              (false).
     113 */
     114RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOid(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fMustIncludeHash);
     115
     116/**
     117 * Tries to get the encryption OID from the given algorithm OID string.
     118 *
     119 * @returns The encryption (cipher) OID  on success, NULL on failure.
     120 * @param   pszAlgorithmOid     The IPRT representation of a X.509 algorithm
     121 *                              identifier object.
     122 * @param   fMustIncludeHash    Whether @a pszAlgorithmOid must include a hash
     123 *                              (true) or whether it is okay to accept pure
     124 *                              encryption IDs as well (false).
     125 */
     126RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(const char *pszAlgorithmOid, bool fMustIncludeHash);
    96127
    97128RTDECL(int) RTCrX509AlgorithmIdentifier_CompareWithString(PCRTCRX509ALGORITHMIDENTIFIER pThis, const char *pszObjId);
     
    155186#define RTCRX509ALGORITHMIDENTIFIERID_MD4               "1.2.840.113549.2.4"
    156187#define RTCRX509ALGORITHMIDENTIFIERID_MD5               "1.2.840.113549.2.5"
     188#define RTCRX509ALGORITHMIDENTIFIERID_SHA0              "1.3.14.3.2.18"
    157189#define RTCRX509ALGORITHMIDENTIFIERID_SHA1              "1.3.14.3.2.26"
    158190#define RTCRX509ALGORITHMIDENTIFIERID_SHA256            "2.16.840.1.101.3.4.2.1"
     
    188220#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA     "2.16.840.1.101.3.4.3.15"
    189221#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA     "2.16.840.1.101.3.4.3.16"
     222#define RTCRX509ALGORITHMIDENTIFIERID_ECDSA                 "1.2.840.10045.2.1"
     223#define RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_ECDSA       "1.2.840.10045.4.1"
     224#define RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_ECDSA     "1.2.840.10045.4.3.1"
     225#define RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_ECDSA     "1.2.840.10045.4.3.2"
     226#define RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_ECDSA     "1.2.840.10045.4.3.3"
     227#define RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_ECDSA     "1.2.840.10045.4.3.4"
     228#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_ECDSA   "2.16.840.1.101.3.4.3.9"
     229#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_ECDSA   "2.16.840.1.101.3.4.3.10"
     230#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_ECDSA   "2.16.840.1.101.3.4.3.11"
     231#define RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_ECDSA   "2.16.840.1.101.3.4.3.12"
    190232/** @} */
    191233
  • trunk/include/iprt/err.h

    r100029 r100442  
    21702170/** Expected RSA public key. */
    21712171#define VERR_CR_PKIX_NOT_RSA_PUBLIC_KEY             (-23524)
     2172/** Expected ECDSA private key. */
     2173#define VERR_CR_PKIX_NOT_ECDSA_PRIVATE_KEY          (-23525)
     2174/** Expected ECDSA public key. */
     2175#define VERR_CR_PKIX_NOT_ECDSA_PUBLIC_KEY           (-23526)
     2176/** OpenSSL failed to decode the key parameters. */
     2177#define VERR_CR_PKIX_OSSL_D2I_KEY_PARAMS_FAILED     (-23527)
    21722178/** @} */
    21732179
     
    22132219/** Failed to generate RSA key. */
    22142220#define VERR_CR_KEY_GEN_FAILED_RSA                  (-23815)
     2221/** Key algorithm parameters not expected. */
     2222#define VERR_CR_KEY_ALGO_PARAMS_UNEXPECTED          (-23816)
     2223/** Key algorithm parameters are required but missing. */
     2224#define VERR_CR_KEY_ALGO_PARAMS_MISSING             (-23817)
     2225/** Key algorithm parameters are not known/supported. */
     2226#define VERR_CR_KEY_ALGO_PARAMS_UNKNOWN             (-23818)
     2227/** Algorithm parameters does not match the key. */
     2228#define VERR_CR_KEY_ALGO_PARAMS_MISMATCH            (-23819)
     2229
    22152230/** @} */
    22162231
  • trunk/include/iprt/mangling.h

    r100422 r100442  
    35283528# define RTCrKeyQueryRsaModulus                         RT_MANGLER(RTCrKeyQueryRsaModulus)
    35293529# define RTCrKeyQueryRsaPrivateExponent                 RT_MANGLER(RTCrKeyQueryRsaPrivateExponent)
     3530# define RTCrKeyVerifyParameterCompatibility            RT_MANGLER(RTCrKeyVerifyParameterCompatibility)
    35303531# define RTCrRc4                                        RT_MANGLER(RTCrRc4)
    35313532# define RTCrRc4SetKey                                  RT_MANGLER(RTCrRc4SetKey)
     
    37093710# define RTCrPkixSignatureVerifyOctetString             RT_MANGLER(RTCrPkixSignatureVerifyOctetString)
    37103711# define RTCrPkixGetCiperOidFromSignatureAlgorithm      RT_MANGLER(RTCrPkixGetCiperOidFromSignatureAlgorithm)
     3712# define RTCrPkixGetCiperOidFromSignatureAlgorithmOid   RT_MANGLER(RTCrPkixGetCiperOidFromSignatureAlgorithmOid)
    37113713# define RTCrPkixPubKeySignDigest                       RT_MANGLER(RTCrPkixPubKeySignDigest)
    37123714# define RTCrPkixPubKeyVerifySignature                  RT_MANGLER(RTCrPkixPubKeyVerifySignature)
     
    38673869# define RTCrX509AlgorithmIdentifier_Delete             RT_MANGLER(RTCrX509AlgorithmIdentifier_Delete)
    38683870# define RTCrX509AlgorithmIdentifier_Enum               RT_MANGLER(RTCrX509AlgorithmIdentifier_Enum)
    3869 # define RTCrX509AlgorithmIdentifier_QueryDigestSize    RT_MANGLER(RTCrX509AlgorithmIdentifier_QueryDigestSize)
    3870 # define RTCrX509AlgorithmIdentifier_QueryDigestType    RT_MANGLER(RTCrX509AlgorithmIdentifier_QueryDigestType)
     3871# define RTCrX509AlgorithmIdentifier_GetDigestSize      RT_MANGLER(RTCrX509AlgorithmIdentifier_GetDigestSize)
     3872# define RTCrX509AlgorithmIdentifier_GetDigestType      RT_MANGLER(RTCrX509AlgorithmIdentifier_GetDigestType)
     3873# define RTCrX509AlgorithmIdentifier_GetEncryptionOid   RT_MANGLER(RTCrX509AlgorithmIdentifier_GetEncryptionOid)
     3874# define RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid RT_MANGLER(RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid)
    38713875# define RTCrX509AlgorithmIdentifiers_Compare           RT_MANGLER(RTCrX509AlgorithmIdentifiers_Compare)
    38723876# define RTCrX509AlgorithmIdentifiers_Delete            RT_MANGLER(RTCrX509AlgorithmIdentifiers_Delete)
  • trunk/src/VBox/Runtime/Makefile.kmk

    r100421 r100442  
    463463        common/crypto/pkix-signature-core.cpp \
    464464        common/crypto/pkix-signature-rsa.cpp \
     465        common/crypto/pkix-signature-ossl.cpp \
    465466        common/crypto/pkix-util.cpp \
    466467        common/crypto/pkix-verify.cpp \
     
    23092310        common/crypto/pkix-signature-core.cpp \
    23102311        common/crypto/pkix-signature-rsa.cpp \
     2312        common/crypto/pkix-signature-ossl.cpp \
    23112313        common/crypto/pkix-util.cpp \
    23122314        common/crypto/pkix-verify.cpp \
  • trunk/src/VBox/Runtime/common/asn1/oiddb.cfg

    r100364 r100442  
    52521.2.840                         = usa
    53531.2.840.10045                   = ansi-x962
     541.2.840.10045.2                 = ansi-x962-keyType
     551.2.840.10045.2.1               = ansi-x962-ecPublicKey
    54561.2.840.10045.4                 = ansi-x962-signatures
    55571.2.840.10045.4.1               = ecdsa-with-sha1
     
    2332351.3.14.3                        = oiw-ssig
    2342361.3.14.3.2                      = oiw-ssig-algorithms
    235 1.3.14.3.2.2                    = oiw-ssig-Md4WithRsa
    236 1.3.14.3.2.3                    = oiw-ssig-Md5WithRsa
    237 1.3.14.3.2.4                    = oiw-ssig-Md4WithRsaEncryption
    238 1.3.14.3.2.15                   = oiw-ssig-ShaWithRsaEncryption
    239 1.3.14.3.2.24                   = oiw-ssig-Md2WithRsaEncryption
    240 1.3.14.3.2.25                   = oiw-ssig-Md5WithRsaEncryption
    241 1.3.14.3.2.26                   = oiw-ssig-Sha1
    242 1.3.14.3.2.29                   = oiw-ssig-Sha1WithRsaEncryption
     2371.3.14.3.2.2                    = oiw-ssig-md4WithRsa
     2381.3.14.3.2.3                    = oiw-ssig-md5WithRsa
     2391.3.14.3.2.4                    = oiw-ssig-md4WithRsaEncryption
     2401.3.14.3.2.14                   = oiw-ssig-mdc2WithRsaSignature
     2411.3.14.3.2.15                   = oiw-ssig-sha0WithRsaSignature
     2421.3.14.3.2.18                   = oiw-ssig-sha0
     2431.3.14.3.2.19                   = oiw-ssig-mdc2
     2441.3.14.3.2.21                   = oiw-ssig-dsaCommonWithSha0
     2451.3.14.3.2.24                   = oiw-ssig-md2WithRsaSignature
     2461.3.14.3.2.25                   = oiw-ssig-md5WithRsaSignature
     2471.3.14.3.2.26                   = oiw-ssig-sha1
     2481.3.14.3.2.29                   = oiw-ssig-sha1WithRsaEncryption
    2432492                               = joint-iso/itu-t
    2442502.1                             = asn.1
  • trunk/src/VBox/Runtime/common/crypto/digest-builtin.cpp

    r98103 r100442  
    261261    RTCR_PKCS1_SHA1_WITH_RSA_OID,
    262262    "1.3.14.3.2.29" /* OIW sha1WithRSASignature */,
     263    RTCR_X962_ECDSA_WITH_SHA1_OID,
    263264    NULL
    264265};
     
    315316{
    316317    RTCR_PKCS1_SHA256_WITH_RSA_OID,
     318    RTCR_X962_ECDSA_WITH_SHA256_OID,
    317319    NULL
    318320};
     
    369371{
    370372    RTCR_PKCS1_SHA512_WITH_RSA_OID,
     373    RTCR_X962_ECDSA_WITH_SHA512_OID,
    371374    NULL
    372375};
     
    423426{
    424427    RTCR_PKCS1_SHA224_WITH_RSA_OID,
     428    RTCR_X962_ECDSA_WITH_SHA224_OID,
    425429    NULL
    426430};
     
    477481{
    478482    RTCR_PKCS1_SHA384_WITH_RSA_OID,
     483    RTCR_X962_ECDSA_WITH_SHA384_OID,
    479484    NULL
    480485};
     
    659664{
    660665    "2.16.840.1.101.3.4.3.13",
     666    RTCR_NIST_SHA3_224_WITH_ECDSA_OID,
    661667    NULL
    662668};
     
    728734{
    729735    "2.16.840.1.101.3.4.3.14",
     736    RTCR_NIST_SHA3_256_WITH_ECDSA_OID,
    730737    NULL
    731738};
     
    797804{
    798805    "2.16.840.1.101.3.4.3.15",
     806    RTCR_NIST_SHA3_384_WITH_ECDSA_OID,
    799807    NULL
    800808};
     
    866874{
    867875    "2.16.840.1.101.3.4.3.16",
     876    RTCR_NIST_SHA3_512_WITH_ECDSA_OID,
    868877    NULL
    869878};
  • trunk/src/VBox/Runtime/common/crypto/key-internal.h

    r98103 r100442  
    8484            RTBIGNUM                Exponent;
    8585        } RsaPublic;
     86
     87        /** RTCRKEYTYPE_ECDSA_PUBLIC. */
     88        struct
     89        {
     90            /** The named curve. */
     91            RTASN1OBJID             NamedCurve;
     92            /** @todo ECPoint. */
     93        } EcdsaPublic;
    8694    } u;
    8795
     
    119127DECLHIDDEN(int) rtCrKeyCreateRsaPrivate(PRTCRKEY phKey, const void *pvKeyBits, uint32_t cbKeyBits,
    120128                                        PRTERRINFO pErrInfo, const char *pszErrorTag);
     129DECLHIDDEN(int) rtCrKeyCreateEcdsaPublic(PRTCRKEY phKey, PCRTASN1DYNTYPE pParameters,
     130                                         const void *pvKeyBits, uint32_t cbKeyBits, PRTERRINFO pErrInfo, const char *pszErrorTag);
    121131
    122132#endif /* !IPRT_INCLUDED_SRC_common_crypto_key_internal_h */
  • trunk/src/VBox/Runtime/common/crypto/key-openssl.cpp

    r98103 r100442  
    3939*   Header Files                                                                                                                 *
    4040*********************************************************************************************************************************/
     41#define LOG_GROUP RTLOGGROUP_CRYPTO
    4142#include "internal/iprt.h"
    4243#include <iprt/crypto/key.h>
    4344
    4445#include <iprt/err.h>
     46#include <iprt/log.h>
     47#include <iprt/mem.h>
    4548#include <iprt/string.h>
    4649#include <iprt/crypto/digest.h>
     
    6164
    6265/**
     66 * Helper that loads key parameters if present.
     67 */
     68static int rtCrKeyToOpenSslKeyLoadParams(RTCRKEY hKey, int idKeyType, EVP_PKEY **ppEvpNewKey, PRTERRINFO pErrInfo)
     69{
     70    int rc = VINF_SUCCESS;
     71    if (   hKey->enmType == RTCRKEYTYPE_ECDSA_PUBLIC
     72        || hKey->enmType == RTCRKEYTYPE_ECDSA_PRIVATE)
     73    {
     74        void          *pvFree = NULL;
     75        const uint8_t *pbRaw  = NULL;
     76        uint32_t       cbRaw  = 0;
     77        if (hKey->enmType == RTCRKEYTYPE_ECDSA_PUBLIC)
     78            rc = RTAsn1EncodeQueryRawBits(&hKey->u.EcdsaPublic.NamedCurve.Asn1Core, &pbRaw, &cbRaw, &pvFree, pErrInfo);
     79        else
     80            AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     81        if (RT_SUCCESS(rc))
     82        {
     83            const unsigned char *puchParams = pbRaw;
     84            EVP_PKEY *pRet = d2i_KeyParams(idKeyType, ppEvpNewKey, &puchParams, cbRaw);
     85            if (pRet != NULL && pRet == *ppEvpNewKey)
     86                rc = VINF_SUCCESS;
     87            else
     88                rc = RTERRINFO_LOG_SET(pErrInfo, VERR_CR_PKIX_OSSL_D2I_KEY_PARAMS_FAILED, "d2i_KeyParams failed");
     89
     90            RTMemTmpFree(pvFree);
     91        }
     92    }
     93    return rc;
     94}
     95
     96
     97/**
     98 * Helper that loads key bits.
     99 */
     100static int rtCrKeyToOpenSslKeyLoadKeyBits(RTCRKEY hKey, int idKeyType, EVP_PKEY **ppEvpNewKey,
     101                                          bool fNeedPublic, PRTERRINFO pErrInfo)
     102{
     103    /*
     104     * Load the key into the structure.
     105     */
     106    const unsigned char *puchPublicKey = hKey->pbEncoded;
     107    EVP_PKEY *pRet;
     108    if (fNeedPublic)
     109        pRet = d2i_PublicKey(idKeyType, ppEvpNewKey, &puchPublicKey, hKey->cbEncoded);
     110    else
     111        pRet = d2i_PrivateKey(idKeyType, ppEvpNewKey, &puchPublicKey, hKey->cbEncoded);
     112    if (pRet != NULL && pRet == *ppEvpNewKey)
     113        return VINF_SUCCESS;
     114
     115    /* Bail out: */
     116    if (fNeedPublic)
     117        return RTERRINFO_LOG_SET(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED, "d2i_PublicKey failed");
     118    return RTERRINFO_LOG_SET(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PRIVATE_KEY_FAILED, "d2i_PrivateKey failed");
     119}
     120
     121
     122/**
    63123 * Creates an OpenSSL key for the given IPRT one, returning the message digest
    64124 * algorithm if desired.
     
    91151            idKeyType = EVP_PKEY_RSA;
    92152            break;
     153
     154        case RTCRKEYTYPE_ECDSA_PUBLIC:
     155        case RTCRKEYTYPE_ECDSA_PRIVATE:
     156            idKeyType = EVP_PKEY_EC;
     157            break;
     158
    93159        default:
    94160            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported key type: %d", hKey->enmType);
     
    103169
    104170    /*
    105      * Load the key into the structure.
    106      */
    107     const unsigned char *puchPublicKey = hKey->pbEncoded;
    108     EVP_PKEY *pRet;
    109     if (fNeedPublic)
    110         *ppEvpKey = pRet = d2i_PublicKey(idKeyType, &pEvpNewKey, &puchPublicKey, hKey->cbEncoded);
    111     else
    112         *ppEvpKey = pRet = d2i_PrivateKey(idKeyType, &pEvpNewKey, &puchPublicKey, hKey->cbEncoded);
    113     if (pRet != NULL && pRet == pEvpNewKey)
    114         return VINF_SUCCESS;
    115 
    116     /* Bail out: */
     171     * Load key parameters and the key into the EVP structure.
     172     */
     173    int rc = rtCrKeyToOpenSslKeyLoadParams(hKey, idKeyType, &pEvpNewKey, pErrInfo);
     174    if (RT_SUCCESS(rc))
     175    {
     176        rc = rtCrKeyToOpenSslKeyLoadKeyBits(hKey, idKeyType, &pEvpNewKey, fNeedPublic, pErrInfo);
     177        if (RT_SUCCESS(rc))
     178        {
     179            *ppEvpKey = pEvpNewKey;
     180            return rc;
     181        }
     182    }
    117183    EVP_PKEY_free(pEvpNewKey);
    118     return RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED,
    119                         fNeedPublic ? "d2i_PublicKey failed" : "d2i_PrivateKey failed");
     184    return rc;
    120185}
    121186
     
    150215    int iAlgoNid = OBJ_txt2nid(pszAlgoObjId);
    151216    if (iAlgoNid == NID_undef)
    152         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN,
    153                              "Unknown public key algorithm [OpenSSL]: %s", pszAlgoObjId);
     217        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN,
     218                                   "Unknown public key algorithm [OpenSSL]: %s", pszAlgoObjId);
    154219    const char *pszAlgoSn = OBJ_nid2sn(iAlgoNid);
    155220
     
    158223    int idAlgoMd = 0;
    159224    if (!OBJ_find_sigid_algs(iAlgoNid, &idAlgoMd, &idAlgoPkey))
    160         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    161                              "OBJ_find_sigid_algs failed on %u (%s, %s)", iAlgoNid, pszAlgoSn, pszAlgoObjId);
     225        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
     226                                   "OBJ_find_sigid_algs failed on %u (%s, %s)", iAlgoNid, pszAlgoSn, pszAlgoObjId);
    162227    if (ppEvpMdType)
    163228    {
    164229        const EVP_MD *pEvpMdType = EVP_get_digestbynid(idAlgoMd);
    165230        if (!pEvpMdType)
    166             return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    167                                  "EVP_get_digestbynid failed on %d (%s, %s)", idAlgoMd, pszAlgoSn, pszAlgoObjId);
     231            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
     232                                       "EVP_get_digestbynid failed on %d (%s, %s)", idAlgoMd, pszAlgoSn, pszAlgoObjId);
    168233        *ppEvpMdType = pEvpMdType;
    169234    }
     
    171236    const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlgoSn);
    172237    if (!pEvpMdType)
    173         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    174                              "EVP_get_digestbyname failed on %s (%s)", pszAlgoSn, pszAlgoObjId);
     238        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
     239                                   "EVP_get_digestbyname failed on %s (%s)", pszAlgoSn, pszAlgoObjId);
    175240    if (ppEvpMdType)
    176241        *ppEvpMdType = pEvpMdType;
     
    182247    EVP_PKEY *pEvpNewKey = EVP_PKEY_new();
    183248    if (!pEvpNewKey)
    184         return RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", iAlgoNid);
     249        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", iAlgoNid);
    185250
    186251    int rc;
     
    196261        {
    197262            /*
    198              * Load the key into the structure.
     263             * Load key parameters and the key into the EVP structure.
    199264             */
    200             const unsigned char *puchPublicKey = hKey->pbEncoded;
    201             EVP_PKEY *pRet;
    202             if (fNeedPublic)
    203                 *ppEvpKey = pRet = d2i_PublicKey(idKeyType, &pEvpNewKey, &puchPublicKey, hKey->cbEncoded);
    204             else
    205                 *ppEvpKey = pRet = d2i_PrivateKey(idKeyType, &pEvpNewKey, &puchPublicKey, hKey->cbEncoded);
    206             if (pRet != NULL && pRet == pEvpNewKey)
    207                 return VINF_SUCCESS;
    208 
    209             /* Bail out: */
    210             rc = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED,
    211                               fNeedPublic ? "d2i_PublicKey failed" : "d2i_PrivateKey failed");
     265            rc = rtCrKeyToOpenSslKeyLoadParams(hKey, idKeyType, &pEvpNewKey, pErrInfo);
     266            if (RT_SUCCESS(rc))
     267            {
     268                rc = rtCrKeyToOpenSslKeyLoadKeyBits(hKey, idKeyType, &pEvpNewKey, fNeedPublic, pErrInfo);
     269                if (RT_SUCCESS(rc))
     270                {
     271                    *ppEvpKey = pEvpNewKey;
     272                    return rc;
     273                }
     274            }
    212275        }
    213276        else
    214277# if OPENSSL_VERSION_NUMBER < 0x10001000 || defined(LIBRESSL_VERSION_NUMBER)
    215             rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_type() failed");
     278            rc = RTERRINFO_LOG_SET(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_type() failed");
    216279# else
    217             rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_base_id() failed");
     280            rc = RTERRINFO_LOG_SET(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_base_id() failed");
    218281    }
    219282    else
    220         rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
    221                            "EVP_PKEY_set_type(%u) failed (sig algo %s)", idAlgoPkey, pszAlgoSn);
     283        rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     284                                 "EVP_PKEY_set_type(%u) failed (sig algo %s)", idAlgoPkey, pszAlgoSn);
    222285# endif
    223286
    224287    EVP_PKEY_free(pEvpNewKey);
     288    *ppEvpKey = NULL;
    225289    return rc;
    226290}
  • trunk/src/VBox/Runtime/common/crypto/key.cpp

    r98103 r100442  
    3939*   Header Files                                                                                                                 *
    4040*********************************************************************************************************************************/
     41#define LOG_GROUP RTLOGGROUP_CRYPTO
    4142#include "internal/iprt.h"
    4243#include <iprt/crypto/key.h>
     
    4546#include <iprt/assert.h>
    4647#include <iprt/err.h>
     48#include <iprt/log.h>
    4749#include <iprt/mem.h>
    4850#include <iprt/memsafer.h>
     
    126128    if (RT_SUCCESS(rc))
    127129    {
    128        /*
    129         * Create a key instance for it.
    130         */
     130        /*
     131         * Create a key instance for it.
     132         */
    131133        PRTCRKEYINT pThis;
    132134        rc = rtCrKeyCreateWorker(&pThis, RTCRKEYTYPE_RSA_PUBLIC, RTCRKEYINT_F_PUBLIC, pvKeyBits, cbKeyBits);
     
    156158
    157159
    158 RTDECL(int) RTCrKeyCreateFromPublicAlgorithmAndBits(PRTCRKEY phKey, PCRTASN1OBJID pAlgorithm, PCRTASN1BITSTRING pPublicKey,
    159                                                     PRTERRINFO pErrInfo, const char *pszErrorTag)
     160/**
     161 * Creates an EC (ECDSA) public key from a DER encoded RTCRX50-PUBLICKEY blob.
     162 *
     163 * @returns IPRT status code.
     164 * @param   phKey       Where to return the key handle.
     165 * @param   pParameters The algorithm parameters, typically namedCurve OID.
     166 * @param   pvKeyBits   The DER encoded RTCRRSAPUBLICKEY blob.
     167 * @param   cbKeyBits   The size of the blob.
     168 * @param   pErrInfo    Where to supply addition error details.  Optional.
     169 * @param   pszErrorTag Error tag. Optional.
     170 */
     171DECLHIDDEN(int) rtCrKeyCreateEcdsaPublic(PRTCRKEY phKey, PCRTASN1DYNTYPE pParameters, const void *pvKeyBits, uint32_t cbKeyBits,
     172                                         PRTERRINFO pErrInfo, const char *pszErrorTag)
     173{
     174#if 0
     175    /*
     176     * Decode the key data first since that's what's most likely to fail here.
     177     */
     178    RTASN1CURSORPRIMARY PrimaryCursor;
     179    RTAsn1CursorInitPrimary(&PrimaryCursor, pvKeyBits, cbKeyBits, pErrInfo, &g_RTAsn1DefaultAllocator,
     180                            RTASN1CURSOR_FLAGS_DER, pszErrorTag ? pszErrorTag : "rsa");
     181    RTCRRSAPUBLICKEY PublicKey;
     182    RT_ZERO(PublicKey);
     183    int rc = RTCrRsaPublicKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &PublicKey, pszErrorTag ? pszErrorTag : "PublicKey");
     184#else
     185    RT_NOREF(pszErrorTag);
     186    int rc = VINF_SUCCESS;
     187#endif
     188    if (RT_SUCCESS(rc))
     189    {
     190        /*
     191         * Check the parameter (see RTC-5480, section 2.1.1).
     192         */
     193        if (   pParameters
     194            && pParameters->enmType == RTASN1TYPE_OBJID
     195            && RTAsn1ObjId_IsPresent(&pParameters->u.ObjId) /* paranoia */)
     196        {
     197            /*
     198             * Create a key instance for it.
     199             */
     200            PRTCRKEYINT pThis;
     201            rc = rtCrKeyCreateWorker(&pThis, RTCRKEYTYPE_ECDSA_PUBLIC, RTCRKEYINT_F_PUBLIC, pvKeyBits, cbKeyBits);
     202            if (RT_SUCCESS(rc))
     203            {
     204                rc = RTAsn1ObjId_Clone(&pThis->u.EcdsaPublic.NamedCurve, &pParameters->u.ObjId, &g_RTAsn1DefaultAllocator);
     205                if (RT_SUCCESS(rc))
     206                {
     207                    /* Done. */
     208#if 0
     209                    RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core);
     210#endif
     211                    *phKey = pThis;
     212                    return VINF_SUCCESS;
     213                }
     214                RTCrKeyRelease(pThis);
     215            }
     216        }
     217        else if (!pParameters || pParameters->enmType == RTASN1TYPE_NOT_PRESENT)
     218            rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISSING,
     219                                     "%s: ECDSA public key expected a namedCurve parameter", pszErrorTag);
     220        else if (pParameters->enmType == RTASN1TYPE_NULL)
     221            rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN,
     222                                     "%s: ECDSA public key expected a namedCurve parameter, found implicitCurve (NULL) instead",
     223                                     pszErrorTag);
     224        else
     225            rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN,
     226                                     "%s: ECDSA public key expected namedCurve parameter, found %d",
     227                                     pszErrorTag, pParameters->enmType);
     228#if 0
     229        RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core);
     230#endif
     231    }
     232    *phKey = NIL_RTCRKEY;
     233    return rc;
     234}
     235
     236
     237RTDECL(int) RTCrKeyCreateFromPublicAlgorithmAndBits(PRTCRKEY phKey, PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters,
     238                                                    PCRTASN1BITSTRING pPublicKey, PRTERRINFO pErrInfo, const char *pszErrorTag)
    160239{
    161240    /*
     
    172251
    173252    /*
    174      * Taking a weird shortcut here.
     253     * Identify the key type from the algorithm ID
    175254     */
    176     PCRTCRPKIXSIGNATUREDESC pDesc = RTCrPkixSignatureFindByObjId(pAlgorithm, NULL);
    177     if (pDesc && strcmp(pDesc->pszObjId, RTCRX509ALGORITHMIDENTIFIERID_RSA) == 0)
    178         return rtCrKeyCreateRsaPublic(phKey,
    179                                       RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey),
    180                                       RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey),
    181                                       pErrInfo, pszErrorTag);
    182     Assert(pDesc == NULL);
     255    const char * const pszEncryptionOid = RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(pAlgorithm->szObjId,
     256                                                                                              false /*fMustIncludeHash*/);
     257    if (pszEncryptionOid)
     258    {
     259        if (strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_RSA) == 0)
     260            return rtCrKeyCreateRsaPublic(phKey,
     261                                          RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey),
     262                                          RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey),
     263                                          pErrInfo, pszErrorTag);
     264        if (strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_ECDSA) == 0)
     265            return rtCrKeyCreateEcdsaPublic(phKey,
     266                                            pParameters,
     267                                            RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey),
     268                                            RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey),
     269                                            pErrInfo, pszErrorTag);
     270    }
     271    Assert(pszEncryptionOid == NULL);
    183272    return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN, "oid=%s", pAlgorithm->szObjId);
    184273}
     
    190279    AssertPtrReturn(pSrc, VERR_INVALID_POINTER);
    191280    AssertReturn(RTCrX509SubjectPublicKeyInfo_IsPresent(pSrc), VERR_INVALID_PARAMETER);
    192     return RTCrKeyCreateFromPublicAlgorithmAndBits(phKey, &pSrc->Algorithm.Algorithm, &pSrc->SubjectPublicKey,
    193                                                    pErrInfo, pszErrorTag);
     281    return RTCrKeyCreateFromPublicAlgorithmAndBits(phKey, &pSrc->Algorithm.Algorithm, &pSrc->Algorithm.Parameters,
     282                                                   &pSrc->SubjectPublicKey, pErrInfo, pszErrorTag);
    194283}
    195284
     
    292381            break;
    293382
     383        case RTCRKEYTYPE_ECDSA_PUBLIC:
     384            RTAsn1ObjId_Delete(&pThis->u.EcdsaPublic.NamedCurve);
     385            break;
     386
     387        case RTCRKEYTYPE_ECDSA_PRIVATE: /* not yet implemented */
    294388        case RTCRKEYTYPE_INVALID:
    295389        case RTCRKEYTYPE_END:
     
    394488}
    395489
     490
     491RTDECL(int) RTCrKeyVerifyParameterCompatibility(RTCRKEY hKey, PCRTASN1DYNTYPE pParameters, bool fForSignature,
     492                                                PCRTASN1OBJID pAlgorithm, PRTERRINFO pErrInfo)
     493{
     494    PRTCRKEYINT pThis = hKey;
     495    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     496    AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, VERR_INVALID_HANDLE);
     497    RT_NOREF(pAlgorithm);
     498
     499    switch (pThis->enmType)
     500    {
     501        /*
     502         * No parameters. Ignore NULL.
     503         */
     504        case RTCRKEYTYPE_RSA_PRIVATE:
     505        case RTCRKEYTYPE_RSA_PUBLIC:
     506            if (   !pParameters
     507                || pParameters->enmType == RTASN1TYPE_NOT_PRESENT
     508                || pParameters->enmType == RTASN1TYPE_NULL)
     509                return VINF_SUCCESS;
     510            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNEXPECTED,
     511                                       "RSA keys does not generally take parameters (enmType=%d)", pParameters->enmType);
     512
     513        /*
     514         * ECDSA requires a parameter.  Currently only the named curve choice is supported.
     515         * RFC-3279 section 2.2.3 states that for ecdsa-with-SHA1 the parameter MUST be
     516         * omitted.  ASSUMING the same applies to the other ecdsa-with-xxxx variants.
     517         */
     518        case RTCRKEYTYPE_ECDSA_PUBLIC:
     519            if (!fForSignature)
     520            {
     521                /* Key rules: Parameters required. */
     522                if (pParameters)
     523                {
     524                    if (pParameters->enmType == RTASN1TYPE_OBJID)
     525                    {
     526                        if (RTAsn1ObjId_Compare(&pParameters->u.ObjId, &pThis->u.EcdsaPublic.NamedCurve) == 0)
     527                            return VINF_SUCCESS;
     528                        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISMATCH,
     529                                                   "ECDSA NamedCurve difference: %s, key uses %s",
     530                                                   pParameters->u.ObjId.szObjId, pThis->u.EcdsaPublic.NamedCurve.szObjId);
     531                    }
     532                    /* We don't implement the other variants. */
     533                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN,
     534                                               "Unexpected ECDSA parameter: enmType=%d", pParameters->enmType);
     535                }
     536                return RTERRINFO_LOG_SET(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISSING, "ECDSA keys requires parameter(s)");
     537            }
     538
     539            /* Hash+ecdsa parameter rules: No parameters */
     540            if (   !pParameters
     541                || pParameters->enmType == RTASN1TYPE_NOT_PRESENT
     542                || pParameters->enmType == RTASN1TYPE_NULL)
     543                return VINF_SUCCESS;
     544            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNEXPECTED,
     545                                       "ECDSA signature should have no parameters (enmType=%d)", pParameters->enmType);
     546
     547        case RTCRKEYTYPE_ECDSA_PRIVATE:
     548            AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     549
     550        case RTCRKEYTYPE_INVALID:
     551        case RTCRKEYTYPE_END:
     552        case RTCRKEYTYPE_32BIT_HACK:
     553            break;
     554    }
     555    AssertFailedReturn(VERR_INTERNAL_ERROR_5);
     556}
     557
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp

    r98103 r100442  
    7878        for (uint32_t i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
    7979        {
    80             if (RTCrX509AlgorithmIdentifier_QueryDigestType(pSignedData->DigestAlgorithms.papItems[i]) == RTDIGESTTYPE_INVALID)
     80            if (   RTCrX509AlgorithmIdentifier_GetDigestType(pSignedData->DigestAlgorithms.papItems[i],
     81                                                             true /*fPureDigestsOnly*/)
     82                == RTDIGESTTYPE_INVALID)
    8183                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM,
    8284                                     "%s: SignedData.DigestAlgorithms[%i] is not known: %s",
  • trunk/src/VBox/Runtime/common/crypto/pkix-sign.cpp

    r98103 r100442  
    140140    if (RT_FAILURE(rcIprt))
    141141        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
    142                              "Unknown private key algorithm [IPRT]: %s", pAlgorithm->szObjId);
     142                             "Unknown private key algorithm [IPRT %Rrc]: %s", rcIprt, pAlgorithm->szObjId);
    143143
    144144    rcIprt = RTCrPkixSignatureSign(hSignature, hDigest, pvSignature, pcbSignature);
     
    154154  && (OPENSSL_VERSION_NUMBER > 0x10000000L) /* 0.9.8 doesn't seem to have EVP_PKEY_CTX_set_signature_md. */
    155155
    156     /* Make sure the algorithm includes the digest and isn't just RSA.  */
    157     const char *pszAlgObjId = pAlgorithm->szObjId;
    158     if (!strcmp(pszAlgObjId, RTCRX509ALGORITHMIDENTIFIERID_RSA))
    159     {
    160         pszAlgObjId = RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pszAlgObjId,
    161                                                                                    RTCrDigestGetAlgorithmOid(hDigest));
    162         AssertMsgStmt(pszAlgObjId, ("enc=%s hash=%s\n", pAlgorithm->szObjId, RTCrDigestGetAlgorithmOid(hDigest)),
    163                       pszAlgObjId = RTCrDigestGetAlgorithmOid(hDigest));
    164     }
     156    /* Make sure the algorithm includes the digest and isn't just RSA, ECDSA or similar.  */
     157    const char *pszAlgObjId = RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pAlgorithm->szObjId,
     158                                                                                           RTCrDigestGetAlgorithmOid(hDigest));
     159    AssertMsgStmt(pszAlgObjId, ("enc=%s hash=%s\n", pAlgorithm->szObjId, RTCrDigestGetAlgorithmOid(hDigest)),
     160                  pszAlgObjId = RTCrDigestGetAlgorithmOid(hDigest));
    165161
    166162    /* Create an EVP private key. */
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-builtin.cpp

    r98103 r100442  
    6464{
    6565    &g_rtCrPkixSigningHashWithRsaDesc,
     66#ifdef IPRT_WITH_OPENSSL
     67    &g_rtCrPkixSigningHashWithEcdsaDesc,
     68#endif
    6669};
    6770
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-builtin.h

    r98103 r100442  
    4444
    4545extern DECL_HIDDEN_DATA(RTCRPKIXSIGNATUREDESC const) g_rtCrPkixSigningHashWithRsaDesc;
     46#ifdef IPRT_WITH_OPENSSL
     47extern DECL_HIDDEN_DATA(RTCRPKIXSIGNATUREDESC const) g_rtCrPkixSigningHashWithEcdsaDesc;
     48#endif
    4649
    4750#endif /* !IPRT_INCLUDED_SRC_common_crypto_pkix_signature_builtin_h */
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-core.cpp

    r98103 r100442  
    103103    AssertPtrReturn(phSignature, VERR_INVALID_POINTER);
    104104    AssertPtrReturn(pDesc, VERR_INVALID_POINTER);
    105     if (pParams)
    106     {
    107         AssertPtrReturn(pParams, VERR_INVALID_POINTER);
    108         if (   pParams->enmType == RTASN1TYPE_NULL
    109             || !RTASN1CORE_IS_PRESENT(&pParams->u.Core))
    110             pParams = NULL;
    111     }
    112105    uint32_t cKeyRefs = RTCrKeyRetain(hKey);
    113106    AssertReturn(cKeyRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     
    129122        if (pDesc->pfnInit)
    130123            rc = pDesc->pfnInit(pDesc, pThis->abState, pvOpaque, fSigning, hKey, pParams);
     124        else
     125            rc = RTCrKeyVerifyParameterCompatibility(hKey, pParams, true /*fForSignature*/,
     126                                                     NULL /*pAlgorithm*/, NULL /*pErrInfo*/);
    131127        if (RT_SUCCESS(rc))
    132128        {
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-rsa.cpp

    r98103 r100442  
    179179    RT_NOREF_PV(pDesc); RT_NOREF_PV(pvState); RT_NOREF_PV(pvOpaque);
    180180
    181     if (pParams)
     181    if (   !pParams
     182        || pParams->enmType == RTASN1TYPE_NULL
     183        || pParams->enmType == RTASN1TYPE_NOT_PRESENT)
     184    { /* likely */ }
     185    else
    182186        return VERR_CR_PKIX_SIGNATURE_TAKES_NO_PARAMETERS;
    183187
     
    479483    RTCR_PKCS1_SHA512T224_WITH_RSA_OID,
    480484    RTCR_PKCS1_SHA512T256_WITH_RSA_OID,
     485    RTCR_NIST_SHA3_224_WITH_RSA_OID,
     486    RTCR_NIST_SHA3_256_WITH_RSA_OID,
     487    RTCR_NIST_SHA3_384_WITH_RSA_OID,
     488    RTCR_NIST_SHA3_512_WITH_RSA_OID,
    481489    /* Note: Note quite sure about these OIW oddballs. */
    482490    "1.3.14.3.2.11" /* OIW rsaSignature */,
  • trunk/src/VBox/Runtime/common/crypto/pkix-util.cpp

    r98103 r100442  
    4545#include <iprt/assert.h>
    4646#include <iprt/err.h>
    47 #include <iprt/string.h>
    4847#include <iprt/crypto/rsa.h>
    4948
    50 #ifdef IPRT_WITH_OPENSSL
    51 # include "internal/iprt-openssl.h"
    52 # include "internal/openssl-pre.h"
    53 # include <openssl/evp.h>
    54 # include "internal/openssl-post.h"
    55 #endif
    5649
    57 
     50RTDECL(const char *) RTCrPkixGetCiperOidFromSignatureAlgorithmOid(const char *pszSignatureOid)
     51{
     52    return RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(pszSignatureOid, true /*fMustIncludeHash*/);
     53}
    5854
    5955
    6056RTDECL(const char *) RTCrPkixGetCiperOidFromSignatureAlgorithm(PCRTASN1OBJID pAlgorithm)
    6157{
    62     /*
    63      * This is all hardcoded, at least for the time being.
    64      */
    65     if (RTAsn1ObjId_StartsWith(pAlgorithm, RTCR_PKCS1_OID))
    66     {
    67         if (RTAsn1ObjIdCountComponents(pAlgorithm) == 7)
    68             switch (RTAsn1ObjIdGetLastComponentsAsUInt32(pAlgorithm))
    69             {
    70                 case 2:
    71                 case 3:
    72                 case 4:
    73                 case 5:
    74                 case 11:
    75                 case 12:
    76                 case 13:
    77                 case 14:
    78                     return RTCR_PKCS1_RSA_OID;
    79                 case 1: AssertFailed();
    80                     RT_FALL_THRU();
    81                 default:
    82                     return NULL;
    83             }
    84     }
    85     /*
    86      * OIW oddballs.
    87      */
    88     else if (RTAsn1ObjId_StartsWith(pAlgorithm, "1.3.14.3.2"))
    89     {
    90         if (RTAsn1ObjIdCountComponents(pAlgorithm) == 6)
    91             switch (RTAsn1ObjIdGetLastComponentsAsUInt32(pAlgorithm))
    92             {
    93                 case 11:
    94                 case 14:
    95                 case 15:
    96                 case 24:
    97                 case 25:
    98                 case 29:
    99                     return RTCR_PKCS1_RSA_OID;
    100                 default:
    101                     return NULL;
    102             }
    103     }
    104 
    105 
    106     return NULL;
     58    return RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(pAlgorithm->szObjId, true /*fMustIncludeHash*/);
    10759}
    10860
     
    13890        else
    13991        {
     92            /** @todo ECDSA when adding signing support.  */
    14093            RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN, "%s", pPublicKeyInfo->Algorithm.Algorithm.szObjId);
    14194            AssertMsgFailed(("unknown key algorithm: %s\n", pPublicKeyInfo->Algorithm.Algorithm.szObjId));
  • trunk/src/VBox/Runtime/common/crypto/pkix-verify.cpp

    r98103 r100442  
    6969    AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_POINTER);
    7070
    71     if (pParameters)
    72     {
    73         AssertPtrReturn(pParameters, VERR_INVALID_POINTER);
    74         if (pParameters->enmType == RTASN1TYPE_NULL)
    75             pParameters = NULL;
    76     }
    77 
    7871    AssertPtrReturn(hPublicKey, VERR_INVALID_POINTER);
    7972    Assert(RTCrKeyHasPublicPart(hPublicKey));
     73    RTCRKEYTYPE const enmKeyType = RTCrKeyGetType(hPublicKey);
     74    AssertReturn(enmKeyType != RTCRKEYTYPE_INVALID, VERR_INVALID_HANDLE);
    8075
    8176    AssertPtrReturn(pSignatureValue, VERR_INVALID_POINTER);
     
    8681
    8782    /*
    88      * Parameters are not currently supported (openssl code path).
    89      */
    90     if (pParameters)
    91         return RTErrInfoSet(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL,
    92                             "Cipher algorithm parameters are not yet supported.");
     83     * Verify that the parameters are compatible with the key.  We ASSUME the
     84     * parameters are for a hash+cryption combination, like those found in
     85     * RTCRX509TBSCERTIFICATE::Signature.  At present, these should NULL (or
     86     * absent) for the two key types we support RSA & ECDSA, which is an
     87     * ASSUMPTION by the OpenSSL code below.
     88     */
     89    int rcIprt = RTCrKeyVerifyParameterCompatibility(hPublicKey, pParameters, true /*fForSignature*/, pAlgorithm, pErrInfo);
     90    AssertRCReturn(rcIprt, rcIprt);
    9391
    9492    /*
     
    9694     */
    9795    RTCRPKIXSIGNATURE hSignature;
    98     int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
     96    rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
    9997    if (RT_FAILURE(rcIprt))
    10098        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
    101                              "Unknown public key algorithm [IPRT]: %s", pAlgorithm->szObjId);
     99                             "Unknown public key algorithm [IPRT %Rrc]: %s", rcIprt, pAlgorithm->szObjId);
    102100
    103101    RTCRDIGEST hDigest;
     
    122120
    123121#ifdef IPRT_WITH_OPENSSL
     122    /* We don't implement digest+cipher parameters in OpenSSL (or at all),
     123       RTCrKeyVerifyParameterCompatibility should ensure we don't get here
     124       (ASSUMING only RSA and ECDSA keys). But, just in case, bail out if we do. */
     125    AssertReturn(   !pParameters
     126                 || pParameters->enmType == RTASN1TYPE_NULL
     127                 || pParameters->enmType == RTASN1TYPE_NOT_PRESENT,
     128                 VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL);
     129
    124130    /*
    125131     * Validate using OpenSSL EVP.
     
    187193    AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_POINTER);
    188194
    189     if (pParameters)
    190     {
    191         AssertPtrReturn(pParameters, VERR_INVALID_POINTER);
    192         if (pParameters->enmType == RTASN1TYPE_NULL)
    193             pParameters = NULL;
    194     }
    195 
    196195    AssertPtrReturn(hPublicKey, VERR_INVALID_POINTER);
    197196    Assert(RTCrKeyHasPublicPart(hPublicKey));
     197    RTCRKEYTYPE const enmKeyType = RTCrKeyGetType(hPublicKey);
     198    AssertReturn(enmKeyType != RTCRKEYTYPE_INVALID, VERR_INVALID_HANDLE);
    198199
    199200    AssertPtrReturn(pvSignedDigest, VERR_INVALID_POINTER);
     
    203204
    204205    /*
    205      * Parameters are not currently supported (openssl code path).
    206      */
    207     if (pParameters)
    208         return RTErrInfoSet(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL,
    209                             "Cipher algorithm parameters are not yet supported.");
     206     * Verify that the parameters are compatible with the key.  We ASSUME the
     207     * parameters are for a hash+cryption combination, like those found in
     208     * RTCRX509TBSCERTIFICATE::Signature.  At present, these should NULL (or
     209     * absent) for the two key types we support RSA & ECDSA, which is an
     210     * ASSUMPTION by the OpenSSL code below.
     211     */
     212    int rcIprt = RTCrKeyVerifyParameterCompatibility(hPublicKey, pParameters, true /*fForSignature*/, pAlgorithm, pErrInfo);
     213    AssertRCReturn(rcIprt, rcIprt);
    210214
    211215    /*
     
    213217     */
    214218    RTCRPKIXSIGNATURE hSignature;
    215     int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
     219    rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
    216220    if (RT_FAILURE(rcIprt))
    217221        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
    218                              "Unknown public key algorithm [IPRT]: %s", pAlgorithm->szObjId);
     222                             "Unknown public key algorithm [IPRT %Rrc]: %s", rcIprt, pAlgorithm->szObjId);
    219223
    220224    rcIprt = RTCrPkixSignatureVerify(hSignature, hDigest, pvSignedDigest, cbSignedDigest);
     
    229233     * Validate using OpenSSL EVP.
    230234     */
    231     /* Combine encryption and digest if the algorithm doesn't specify the digest type. */
    232     const char *pszAlgObjId = pAlgorithm->szObjId;
    233     if (!strcmp(pszAlgObjId, RTCRX509ALGORITHMIDENTIFIERID_RSA))
    234     {
    235         pszAlgObjId = RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pszAlgObjId,
    236                                                                                    RTCrDigestGetAlgorithmOid(hDigest));
    237         AssertMsgStmt(pszAlgObjId, ("enc=%s hash=%s\n", pAlgorithm->szObjId, RTCrDigestGetAlgorithmOid(hDigest)),
    238                       pszAlgObjId = RTCrDigestGetAlgorithmOid(hDigest));
    239     }
     235    /* Make sure the algorithm includes the digest and isn't just RSA, ECDSA or similar.  */
     236    const char *pszAlgObjId = RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pAlgorithm->szObjId,
     237                                                                                           RTCrDigestGetAlgorithmOid(hDigest));
     238    AssertMsgStmt(pszAlgObjId, ("enc=%s hash=%s\n", pAlgorithm->szObjId, RTCrDigestGetAlgorithmOid(hDigest)),
     239                  pszAlgObjId = RTCrDigestGetAlgorithmOid(hDigest));
     240
     241    /* We don't implement digest+cipher parameters in OpenSSL (or at all),
     242       RTCrKeyVerifyParameterCompatibility should ensure we don't get here
     243       (ASSUMING only RSA and ECDSA keys). But, just in case, bail out if we do. */
     244    AssertReturn(   !pParameters
     245                 || pParameters->enmType == RTASN1TYPE_NULL
     246                 || pParameters->enmType == RTASN1TYPE_NOT_PRESENT,
     247                 VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL);
    240248
    241249    /* Create an EVP public key. */
     
    305313    RTCRKEY hPublicKey;
    306314    int rc = RTCrKeyCreateFromPublicAlgorithmAndBits(&hPublicKey, &pCertPubKeyInfo->Algorithm.Algorithm,
     315                                                     &pCertPubKeyInfo->Algorithm.Parameters,
    307316                                                     &pCertPubKeyInfo->SubjectPublicKey, pErrInfo, NULL);
    308317    if (RT_SUCCESS(rc))
    309318    {
    310         rc = RTCrPkixPubKeyVerifySignedDigest(&pCertPubKeyInfo->Algorithm.Algorithm, hPublicKey,
    311                                               &pCertPubKeyInfo->Algorithm.Parameters, pvSignedDigest, cbSignedDigest,
    312                                               hDigest, pErrInfo);
     319        /** @todo r=bird (2023-07-06): This ASSUMES no digest+cipher parameters, which
     320         *        is the case for RSA and ECDSA. */
     321        rc = RTCrPkixPubKeyVerifySignedDigest(&pCertPubKeyInfo->Algorithm.Algorithm, hPublicKey, NULL,
     322                                              pvSignedDigest, cbSignedDigest, hDigest, pErrInfo);
    313323
    314324        uint32_t cRefs = RTCrKeyRelease(hPublicKey);
  • trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp

    r98103 r100442  
    8282    if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)
    8383    {
    84         if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pIndData->DigestInfo.DigestAlgorithm) == RTDIGESTTYPE_INVALID)
     84        if (   RTCrX509AlgorithmIdentifier_GetDigestType(&pIndData->DigestInfo.DigestAlgorithm, true /*fPureDigestsOnly*/)
     85            == RTDIGESTTYPE_INVALID)
    8586            return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_UNKNOWN_DIGEST_ALGO,
    8687                                 "SpcIndirectDataContent DigestAlgortihm is not known: %s",
     
    8889    }
    8990
    90     uint32_t cbDigest = RTCrX509AlgorithmIdentifier_QueryDigestSize(&pIndData->DigestInfo.DigestAlgorithm);
     91    uint32_t cbDigest = RTCrX509AlgorithmIdentifier_GetDigestSize(&pIndData->DigestInfo.DigestAlgorithm,
     92                                                                  true /*fPureDigestsOnly*/);
    9193    if (   pIndData->DigestInfo.Digest.Asn1Core.cb != cbDigest
    9294        && (cbDigest != UINT32_MAX || (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)))
  • trunk/src/VBox/Runtime/common/crypto/x509-core.cpp

    r100364 r100442  
    4545#include <iprt/string.h>
    4646#include <iprt/uni.h>
     47#include <iprt/crypto/pkix.h>
     48#ifdef RT_STRICT
     49# include <iprt/crypto/digest.h>
     50#endif
    4751
    4852#include "x509-internal.h"
     53
     54
     55/*********************************************************************************************************************************
     56*   Internal Functions                                                                                                           *
     57*********************************************************************************************************************************/
     58#ifdef RT_STRICT
     59static void rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore(void);
     60#endif
    4961
    5062
     
    7385 */
    7486
    75 RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_QueryDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis)
     87/**
     88 * String table with the encryption OIDs (used by g_aSignatureOidInfo).
     89 */
     90static const char * const g_apszEncryptionOids[] =
     91{
     92    NULL,
     93#define IDX_ENCRYPTION_NIL      0
     94    RTCR_X962_ECDSA_OID,
     95#define IDX_ENCRYPTION_ECDSA    1
     96    RTCR_PKCS1_RSA_OID,
     97#define IDX_ENCRYPTION_RSA      2
     98};
     99
     100/**
     101 * Information about an algorithm identifier.
     102 */
     103typedef struct RTCRX509ALGORITHIDENTIFIERINTERNALINFO
     104{
     105    /** The signature OID. */
     106    const char     *pszSignatureOid;
     107    /** Index into g_apszEncryptionOids of the encryption ODI.
     108     * This is IDX_ENCRYPTION_NIL for hashes. */
     109    uint8_t         idxEncryption;
     110    /** The message digest type specified by the OID.
     111     * This is set to RTDIGESTTYPE_INVALID in two cases:
     112     *      1. Pure encryption algorithm OID (cBitsDigest also zero).
     113     *      2. The hash is so esoteric that IPRT doesn't support it. */
     114    uint8_t         enmDigestType;
     115    /** The digest size in bits.
     116     * This is ZERO if the OID does not include an hash. */
     117    uint16_t        cBitsDigest;
     118} RTCRX509ALGORITHIDENTIFIERINTERNALINFO;
     119typedef RTCRX509ALGORITHIDENTIFIERINTERNALINFO const *PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO;
     120
     121/**
     122 * Signature to encryption OID.
     123 *
     124 * @note This is sorted to allow binary searching.
     125 * @note This origins in pkix-utils.cpp, which is why it uses the other set of
     126 *       OID defines.
     127 */
     128static RTCRX509ALGORITHIDENTIFIERINTERNALINFO const g_aSignatureOidInfo[] =
     129{
     130    { /*1.0.10118.3.0.55*/     RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_INVALID,    512, },
     131
     132    { /*1.2.840.10045.2.1    */     RTCR_X962_ECDSA_OID,                IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_INVALID,    0, },
     133    { /*1.2.840.10045.4.1    */     RTCR_X962_ECDSA_WITH_SHA1_OID,      IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA1,       160, },
     134    { /*1.2.840.10045.4.3.1  */     RTCR_X962_ECDSA_WITH_SHA224_OID,    IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA224,     224, },
     135    { /*1.2.840.10045.4.3.2  */     RTCR_X962_ECDSA_WITH_SHA256_OID,    IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA256,     256, },
     136    { /*1.2.840.10045.4.3.3  */     RTCR_X962_ECDSA_WITH_SHA384_OID,    IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA384,     384, },
     137    { /*1.2.840.10045.4.3.4  */     RTCR_X962_ECDSA_WITH_SHA512_OID,    IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA512,     512, },
     138
     139    { /*1.2.840.113549.1.1.1 */     RTCR_PKCS1_RSA_OID,                 IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_INVALID,    0, },
     140    { /*1.2.840.113549.1.1.11*/     RTCR_PKCS1_SHA256_WITH_RSA_OID,     IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA256,     256, },
     141    { /*1.2.840.113549.1.1.12*/     RTCR_PKCS1_SHA384_WITH_RSA_OID,     IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA384,     384, },
     142    { /*1.2.840.113549.1.1.13*/     RTCR_PKCS1_SHA512_WITH_RSA_OID,     IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA512,     512, },
     143    { /*1.2.840.113549.1.1.14*/     RTCR_PKCS1_SHA224_WITH_RSA_OID,     IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA224,     224, },
     144    { /*1.2.840.113549.1.1.15*/     RTCR_PKCS1_SHA512T224_WITH_RSA_OID, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA512T224, 224, },
     145    { /*1.2.840.113549.1.1.16*/     RTCR_PKCS1_SHA512T256_WITH_RSA_OID, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA512T256, 256, },
     146    { /*1.2.840.113549.1.1.2*/      RTCR_PKCS1_MD2_WITH_RSA_OID,        IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_MD2,        128, },
     147    { /*1.2.840.113549.1.1.3*/      RTCR_PKCS1_MD4_WITH_RSA_OID,        IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_MD4,        128, },
     148    { /*1.2.840.113549.1.1.4*/      RTCR_PKCS1_MD5_WITH_RSA_OID,        IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_MD5,        128, },
     149    { /*1.2.840.113549.1.1.5*/      RTCR_PKCS1_SHA1_WITH_RSA_OID,       IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA1,       160, },
     150
     151    { /*1.2.840.113549.2.2*/        RTCRX509ALGORITHMIDENTIFIERID_MD2,  IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_MD2,        128, },
     152    { /*1.2.840.113549.2.4*/        RTCRX509ALGORITHMIDENTIFIERID_MD4,  IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_MD4,        128, },
     153    { /*1.2.840.113549.2.5*/        RTCRX509ALGORITHMIDENTIFIERID_MD5,  IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_MD5,        128, },
     154
     155    /* oddballs for which we don't support the padding (skip?): */
     156  //{  "1.3.14.3.2.11"                                /*rsaSignature*/, IDX_ENCRYPTION_RSA/*?*/, RTDIGESTTYPE_INVALID, 0, },
     157    {  "1.3.14.3.2.14"      /*mdc2WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_INVALID,    0, },
     158  //{  "1.3.14.3.2.15"      /*sha0WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_INVALID,    160, },
     159    {  "1.3.14.3.2.24"       /*md2WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_MD2,        128, },
     160    {  "1.3.14.3.2.25"       /*md5WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_MD5,        128, },
     161    { /*1.3.14.3.2.26*/             RTCRX509ALGORITHMIDENTIFIERID_SHA1, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_SHA1,       160, },
     162    {  "1.3.14.3.2.29"           /*sha1WithRSAEncryption (obsolete?)*/, IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA1,       160, },
     163
     164    { /*2.16.840.1.101.3.4.2.1*/  RTCRX509ALGORITHMIDENTIFIERID_SHA256, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_SHA256,     256, },
     165    { /*2.16.840.1.101.3.4.2.10*/ RTCRX509ALGORITHMIDENTIFIERID_SHA3_512, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_512,   512, },
     166    { /*2.16.840.1.101.3.4.2.2*/  RTCRX509ALGORITHMIDENTIFIERID_SHA384, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_SHA384,     384, },
     167    { /*2.16.840.1.101.3.4.2.3*/  RTCRX509ALGORITHMIDENTIFIERID_SHA512, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_SHA512,     512, },
     168    { /*2.16.840.1.101.3.4.2.4*/  RTCRX509ALGORITHMIDENTIFIERID_SHA224, IDX_ENCRYPTION_NIL,   RTDIGESTTYPE_SHA224,     224, },
     169    { /*2.16.840.1.101.3.4.2.5*/ RTCRX509ALGORITHMIDENTIFIERID_SHA512T224,IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA512T224, 224, },
     170    { /*2.16.840.1.101.3.4.2.6*/ RTCRX509ALGORITHMIDENTIFIERID_SHA512T256,IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA512T256, 256, },
     171    { /*2.16.840.1.101.3.4.2.7*/  RTCRX509ALGORITHMIDENTIFIERID_SHA3_224, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_224,   224, },
     172    { /*2.16.840.1.101.3.4.2.8*/  RTCRX509ALGORITHMIDENTIFIERID_SHA3_256, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_256,   256, },
     173    { /*2.16.840.1.101.3.4.2.9*/  RTCRX509ALGORITHMIDENTIFIERID_SHA3_384, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_384,   384, },
     174
     175    { /*2.16.840.1.101.3.4.3.10*/   RTCR_NIST_SHA3_256_WITH_ECDSA_OID,  IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_256,   256, },
     176    { /*2.16.840.1.101.3.4.3.11*/   RTCR_NIST_SHA3_384_WITH_ECDSA_OID,  IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_384,   384, },
     177    { /*2.16.840.1.101.3.4.3.12*/   RTCR_NIST_SHA3_512_WITH_ECDSA_OID,  IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_512,   512, },
     178    { /*2.16.840.1.101.3.4.3.13*/   RTCR_NIST_SHA3_224_WITH_RSA_OID,    IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA3_224,   224, },
     179    { /*2.16.840.1.101.3.4.3.14*/   RTCR_NIST_SHA3_256_WITH_RSA_OID,    IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA3_256,   256, },
     180    { /*2.16.840.1.101.3.4.3.15*/   RTCR_NIST_SHA3_384_WITH_RSA_OID,    IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA3_384,   384, },
     181    { /*2.16.840.1.101.3.4.3.16*/   RTCR_NIST_SHA3_512_WITH_RSA_OID,    IDX_ENCRYPTION_RSA,   RTDIGESTTYPE_SHA3_512,   512, },
     182    { /*2.16.840.1.101.3.4.3.9*/    RTCR_NIST_SHA3_224_WITH_ECDSA_OID,  IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_224,   224, },
     183};
     184
     185/**
     186 * Encryption and digest combining.
     187 *
     188 * This is a subset of g_aSignatureOidInfo.
     189 * @todo Organize this more efficiently...
     190 */
     191typedef struct RTCRX509ALGORITHIDENTIFIERCOMBINING
     192{
     193    const char *pszDigestOid;
     194    const char *pszEncryptedDigestOid;
     195} RTCRX509ALGORITHIDENTIFIERCOMBINING;
     196typedef RTCRX509ALGORITHIDENTIFIERCOMBINING const *PCRTCRX509ALGORITHIDENTIFIERCOMBINING;
     197
     198#undef MY_COMBINE
     199#define MY_COMBINE(a_Encrypt, a_Digest) \
     200        { RTCRX509ALGORITHMIDENTIFIERID_ ## a_Digest, \
     201          RTCRX509ALGORITHMIDENTIFIERID_ ## a_Digest ## _WITH_ ## a_Encrypt }
     202
     203/** Digest and encryption combinations for ECDSA. */
     204static RTCRX509ALGORITHIDENTIFIERCOMBINING const g_aDigestAndEncryptionEcdsa[] =
     205{
     206    MY_COMBINE(ECDSA, SHA1),
     207    MY_COMBINE(ECDSA, SHA224),
     208    MY_COMBINE(ECDSA, SHA256),
     209    MY_COMBINE(ECDSA, SHA384),
     210    MY_COMBINE(ECDSA, SHA512),
     211    MY_COMBINE(ECDSA, SHA3_224),
     212    MY_COMBINE(ECDSA, SHA3_256),
     213    MY_COMBINE(ECDSA, SHA3_384),
     214    MY_COMBINE(ECDSA, SHA3_512),
     215};
     216
     217/** Digest and encryption combinations for RSA. */
     218static RTCRX509ALGORITHIDENTIFIERCOMBINING const g_aDigestAndEncryptionRsa[] =
     219{
     220    MY_COMBINE(RSA, SHA1),
     221    MY_COMBINE(RSA, SHA256),
     222    MY_COMBINE(RSA, SHA512),
     223    MY_COMBINE(RSA, SHA384),
     224    MY_COMBINE(RSA, MD5),
     225    MY_COMBINE(RSA, MD2),
     226    MY_COMBINE(RSA, MD4),
     227    MY_COMBINE(RSA, SHA224),
     228    MY_COMBINE(RSA, SHA512T224),
     229    MY_COMBINE(RSA, SHA512T256),
     230    MY_COMBINE(RSA, SHA3_224),
     231    MY_COMBINE(RSA, SHA3_256),
     232    MY_COMBINE(RSA, SHA3_384),
     233    MY_COMBINE(RSA, SHA3_512),
     234};
     235
     236#undef MY_COMBINE
     237
     238/**
     239 * Table running parallel to g_apszEncryptionOids.
     240 */
     241static struct
     242{
     243    PCRTCRX509ALGORITHIDENTIFIERCOMBINING   paCombinations;
     244    size_t                                  cCombinations;
     245} const g_aDigestAndEncryption[] =
     246{
     247    /* [IDX_ENCRYPTION_NIL]   = */ { NULL, 0 },
     248    /* [IDX_ENCRYPTION_ECDSA] = */ { &g_aDigestAndEncryptionEcdsa[0], RT_ELEMENTS(g_aDigestAndEncryptionEcdsa) },
     249    /* [IDX_ENCRYPTION_RSA]   = */ { &g_aDigestAndEncryptionRsa[0],   RT_ELEMENTS(g_aDigestAndEncryptionRsa) },
     250};
     251AssertCompile(IDX_ENCRYPTION_NIL == 0 && IDX_ENCRYPTION_ECDSA == 1 && IDX_ENCRYPTION_RSA == 2);
     252
     253
     254/**
     255 * Looks up info we've got on a algorithm identifier.
     256 */
     257static PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO rtCrX509AlgorithmIdentifier_LookupInfoByOid(const char *pszSignatureOid)
     258{
     259#ifdef RT_STRICT
     260    /*
     261     * Do internal santiy checking on first call.
     262     */
     263    static bool volatile s_fChecked = false;
     264    if (RT_LIKELY(s_fChecked))
     265    { /* likely */ }
     266    else
     267    {
     268        s_fChecked = true; /* Must be set before the call, as the callee will calls us again. */
     269        rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore();
     270    }
     271#endif
     272
     273    /*
     274     * Do a binary search of g_aSignatureOidInfo.
     275     */
     276    size_t iFirst = 0;
     277    size_t iEnd   = RT_ELEMENTS(g_aSignatureOidInfo);
     278    for (;;)
     279    {
     280        size_t const i     = iFirst + (iEnd - iFirst) / 2;
     281        int const    iDiff = strcmp(pszSignatureOid, g_aSignatureOidInfo[i].pszSignatureOid);
     282        if (iDiff < 0)
     283        {
     284            if (i > iFirst)
     285                iEnd = i;
     286            else
     287                return NULL;
     288        }
     289        else if (iDiff > 0)
     290        {
     291            if (i + 1 < iEnd)
     292                iFirst = i + 1;
     293            else
     294                return NULL;
     295        }
     296        else
     297            return &g_aSignatureOidInfo[i];
     298    }
     299}
     300
     301#ifdef RT_STRICT
     302/**
     303 * Check that the g_aSignatureOidInfo and g_aDigestAndEncryption makes sense and
     304 * matches up with one another and other IPRT information sources.
     305 */
     306static void rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore(void)
     307{
     308    /* Check that binary searching work and that digest info matches up: */
     309    for (size_t i = 1; i < RT_ELEMENTS(g_aSignatureOidInfo); i++)
     310        Assert(strcmp(g_aSignatureOidInfo[i].pszSignatureOid, g_aSignatureOidInfo[i - 1].pszSignatureOid) > 0);
     311    for (size_t i = 0; i < RT_ELEMENTS(g_aSignatureOidInfo); i++)
     312    {
     313        PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo
     314            = rtCrX509AlgorithmIdentifier_LookupInfoByOid(g_aSignatureOidInfo[i].pszSignatureOid);
     315        Assert(pInfo && pInfo->pszSignatureOid == g_aSignatureOidInfo[i].pszSignatureOid);
     316
     317        /* If the digest type is RTDIGESTTYPE_INVALID, we must have an pure encryption entry or an obscure hash function. */
     318        if (g_aSignatureOidInfo[i].enmDigestType != RTDIGESTTYPE_INVALID)
     319            Assert(   RTCrDigestTypeToHashSize((RTDIGESTTYPE)g_aSignatureOidInfo[i].enmDigestType) * 8
     320                   == g_aSignatureOidInfo[i].cBitsDigest);
     321        else
     322            Assert(g_aSignatureOidInfo[i].cBitsDigest == 0 || g_aSignatureOidInfo[i].idxEncryption == IDX_ENCRYPTION_NIL);
     323
     324# ifdef IN_RING3
     325        /* Check with the RTCrDigestFindByObjIdString API: */
     326        RTDIGESTTYPE enmDigestType2 = (RTDIGESTTYPE)g_aSignatureOidInfo[i].enmDigestType;
     327#  if defined(IPRT_WITHOUT_DIGEST_MD2) || defined(IPRT_WITHOUT_DIGEST_MD4) || defined(IPRT_WITHOUT_DIGEST_MD5) \
     328|| defined(IPRT_WITHOUT_SHA512T224) || defined(IPRT_WITHOUT_SHA512T256) || defined(IPRT_WITHOUT_SHA3)
     329        switch (enmDigestType2)
     330        {
     331            default: break;
     332#   ifdef IPRT_WITHOUT_DIGEST_MD2
     333            case RTDIGESTTYPE_MD2:
     334#   endif
     335#   ifdef IPRT_WITHOUT_DIGEST_MD4
     336            case RTDIGESTTYPE_MD4:
     337#   endif
     338#   ifdef IPRT_WITHOUT_DIGEST_MD5
     339            case RTDIGESTTYPE_MD5:
     340#   endif
     341#   ifdef IPRT_WITHOUT_SHA512T224
     342            case RTDIGESTTYPE_SHA512T224:
     343#   endif
     344#   ifdef IPRT_WITHOUT_SHA512T256
     345            case RTDIGESTTYPE_SHA512T256:
     346#   endif
     347#   ifdef IPRT_WITHOUT_SHA3
     348            case RTDIGESTTYPE_SHA3_224:
     349            case RTDIGESTTYPE_SHA3_256:
     350            case RTDIGESTTYPE_SHA3_384:
     351            case RTDIGESTTYPE_SHA3_512:
     352#   endif
     353                enmDigestType2 = RTDIGESTTYPE_INVALID;
     354                break;
     355        }
     356#  endif
     357        PCRTCRDIGESTDESC const pDigestDesc = RTCrDigestFindByObjIdString(g_aSignatureOidInfo[i].pszSignatureOid,
     358                                                                         NULL /*ppvOpaque*/);
     359        if (pDigestDesc)
     360        {
     361            AssertMsg(pDigestDesc->enmType == enmDigestType2,
     362                      ("%s pDigestDesc=%s enmDigestType2=%s\n",  g_aSignatureOidInfo[i].pszSignatureOid,
     363                       RTCrDigestTypeToName(pDigestDesc->enmType), RTCrDigestTypeToName(enmDigestType2)));
     364            Assert(pDigestDesc->cbHash * 8 == g_aSignatureOidInfo[i].cBitsDigest);
     365        }
     366        else
     367            AssertMsg(enmDigestType2 == RTDIGESTTYPE_INVALID,
     368                      ("%s enmDigestType2=%s\n", g_aSignatureOidInfo[i].pszSignatureOid, RTCrDigestTypeToName(enmDigestType2)));
     369# endif /* IN_RING3 */
     370
     371
     372# ifdef IN_RING3
     373        /* Look it up the encryption descriptor. */
     374        const char * const pszCheckEncryptId = g_apszEncryptionOids[g_aSignatureOidInfo[i].idxEncryption];
     375        PCRTCRPKIXSIGNATUREDESC const pSigDesc = RTCrPkixSignatureFindByObjIdString(g_aSignatureOidInfo[i].pszSignatureOid,
     376                                                                                    NULL /*ppvOpaque*/);
     377        if (pSigDesc)
     378            Assert(pszCheckEncryptId && strcmp(pSigDesc->pszObjId, pszCheckEncryptId) == 0);
     379#  ifdef IPRT_WITH_OPENSSL /* No ECDSA implementation w/o OpenSSL at the moment. */
     380        else
     381            AssertMsg(!pSigDesc && pInfo->idxEncryption == IDX_ENCRYPTION_NIL, ("%s\n", g_aSignatureOidInfo[i].pszSignatureOid));
     382#  endif
     383# endif /* IN_RING3 */
     384    }
     385
     386    /*
     387     * Check that everything in g_aDigestAndEncryption is resolvable here and that the info matches up.
     388     */
     389    for (size_t idxEncryption = IDX_ENCRYPTION_NIL; idxEncryption < RT_ELEMENTS(g_aDigestAndEncryption); idxEncryption++)
     390    {
     391        PCRTCRX509ALGORITHIDENTIFIERCOMBINING const paCombinations = g_aDigestAndEncryption[idxEncryption].paCombinations;
     392        size_t const                                cCombinations  = g_aDigestAndEncryption[idxEncryption].cCombinations;
     393        for (size_t i = 0; i < cCombinations; i++)
     394        {
     395            PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo
     396                = rtCrX509AlgorithmIdentifier_LookupInfoByOid(paCombinations[i].pszEncryptedDigestOid);
     397            AssertContinue(pInfo);
     398            Assert(strcmp(paCombinations[i].pszEncryptedDigestOid, pInfo->pszSignatureOid) == 0);
     399            Assert(pInfo->idxEncryption == idxEncryption);
     400            Assert(strcmp(paCombinations[i].pszDigestOid,
     401                          RTCrDigestTypeToAlgorithmOid((RTDIGESTTYPE)pInfo->enmDigestType)) == 0);
     402        }
     403    }
     404}
     405#endif /* RT_STRICT */
     406
     407
     408RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_GetDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly)
    76409{
    77410    AssertPtrReturn(pThis, RTDIGESTTYPE_INVALID);
    78     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5))
    79         return RTDIGESTTYPE_MD5;
    80     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1))
    81         return RTDIGESTTYPE_SHA1;
    82     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256))
    83         return RTDIGESTTYPE_SHA256;
    84     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512))
    85         return RTDIGESTTYPE_SHA512;
    86 
    87     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384))
    88         return RTDIGESTTYPE_SHA384;
    89     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224))
    90         return RTDIGESTTYPE_SHA224;
    91     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224))
    92         return RTDIGESTTYPE_SHA512T224;
    93     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256))
    94         return RTDIGESTTYPE_SHA512T256;
    95 
    96     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224))
    97         return RTDIGESTTYPE_SHA3_224;
    98     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256))
    99         return RTDIGESTTYPE_SHA3_256;
    100     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384))
    101         return RTDIGESTTYPE_SHA3_384;
    102     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512))
    103         return RTDIGESTTYPE_SHA3_512;
    104     return RTDIGESTTYPE_INVALID;
    105 }
    106 
    107 
    108 RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_QueryDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis)
     411    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId);
     412    return pInfo && (!fPureDigestsOnly || pInfo->idxEncryption == IDX_ENCRYPTION_NIL)
     413         ? (RTDIGESTTYPE)pInfo->enmDigestType : RTDIGESTTYPE_INVALID;
     414}
     415
     416
     417RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_GetDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly)
    109418{
    110419    AssertPtrReturn(pThis, UINT32_MAX);
    111 
    112     /* common */
    113     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5))
    114         return 128 / 8;
    115     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1))
    116         return 160 / 8;
    117     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256))
    118         return 256 / 8;
    119     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512))
    120         return 512 / 8;
    121 
    122     /* Less common. */
    123     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD2))
    124         return 128 / 8;
    125     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD4))
    126         return 128 / 8;
    127     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384))
    128         return 384 / 8;
    129     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224))
    130         return 224 / 8;
    131     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224))
    132         return 224 / 8;
    133     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256))
    134         return 256 / 8;
    135     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224))
    136         return 224 / 8;
    137     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256))
    138         return 256 / 8;
    139     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384))
    140         return 384 / 8;
    141     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512))
    142         return 512 / 8;
    143     if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
    144         return 512 / 8;
    145 
    146     return UINT32_MAX;
     420    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId);
     421    return pInfo && (!fPureDigestsOnly || pInfo->idxEncryption == IDX_ENCRYPTION_NIL)
     422         ? pInfo->cBitsDigest / 8 : UINT32_MAX;
    147423}
    148424
     
    157433                                                                              const char *pszEncryptedDigestOid)
    158434{
    159     /* common */
    160     if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5))
    161     {
    162         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA))
    163             return 0;
    164     }
    165     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1))
    166     {
    167         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA))
    168             return 0;
    169     }
    170     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256))
    171     {
    172         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA))
    173             return 0;
    174     }
    175     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512))
    176     {
    177         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA))
    178             return 0;
    179     }
    180     /* Less common. */
    181     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2))
    182     {
    183         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA))
    184             return 0;
    185     }
    186     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4))
    187     {
    188         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA))
    189             return 0;
    190     }
    191     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384))
    192     {
    193         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA))
    194             return 0;
    195     }
    196     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224))
    197     {
    198         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA))
    199             return 0;
    200     }
    201     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224))
    202     {
    203         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA))
    204             return 0;
    205     }
    206     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256))
    207     {
    208         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA))
    209             return 0;
    210     }
    211     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224))
    212     {
    213         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA))
    214             return 0;
    215     }
    216     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256))
    217     {
    218         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA))
    219             return 0;
    220     }
    221     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384))
    222     {
    223         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA))
    224             return 0;
    225     }
    226     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512))
    227     {
    228         if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA))
    229             return 0;
    230     }
    231     else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
    232     {
    233         /* ?? */
    234     }
    235     else
    236         return -1;
    237     return 1;
     435    /*
     436     * Lookup the digest and encrypted digest OIDs.
     437     */
     438    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pDigest  = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszDigestOid);
     439    AssertMsgReturn(pDigest,                                      ("pszDigestOid=%s\n", pszDigestOid), -1);
     440    AssertMsgReturn(pDigest->idxEncryption == IDX_ENCRYPTION_NIL, ("pszDigestOid=%s\n", pszDigestOid), -1);
     441    AssertMsgReturn(pDigest->cBitsDigest   != 0,                  ("pszDigestOid=%s\n", pszDigestOid), -1);
     442
     443    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pEncrypt = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszEncryptedDigestOid);
     444    AssertMsgReturn(pEncrypt,                                        ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1);
     445    AssertMsgReturn(pEncrypt->idxEncryption != IDX_ENCRYPTION_NIL,   ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1);
     446    AssertMsgReturn(pEncrypt->enmDigestType != RTDIGESTTYPE_INVALID, ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1);
     447
     448    return pDigest->enmDigestType == pEncrypt->enmDigestType ? 0 : 1;
    238449}
    239450
     
    249460                                                                                  const char *pszDigestOid)
    250461{
    251     /* RSA: */
    252     if (!strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_RSA))
    253     {
    254         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5)
    255             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA))
    256             return RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA;
    257         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1)
    258             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA))
    259             return RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA;
    260         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256)
    261             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA))
    262             return RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA;
    263         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512)
    264             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA))
    265             return RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA;
    266         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2)
    267             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA))
    268             return RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA;
    269         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4)
    270             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA))
    271             return RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA;
    272         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384)
    273             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA))
    274             return RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA;
    275         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224)
    276             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA))
    277             return RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA;
    278         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224)
    279             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA))
    280             return RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA;
    281         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256)
    282             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA))
    283             return RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA;
    284         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224)
    285             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA))
    286             return RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA;
    287         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256)
    288             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA))
    289             return RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA;
    290         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384)
    291             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA))
    292             return RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA;
    293         if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512)
    294             || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA))
    295             return RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA;
    296 
    297         /* if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
    298             return ???; */
    299     }
    300     else if (RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid(pszDigestOid, pszEncryptionOid) == 0)
    301         return pszEncryptionOid;
    302 
    303     AssertMsgFailed(("enc=%s hash=%s\n", pszEncryptionOid, pszDigestOid));
     462    /*
     463     * We can look up the two OIDs and see what they actually are.
     464     */
     465    /* The digest OID should be a pure hash algorithm, however we also accept
     466       the already combined algorithm. */
     467    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pDigest  = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszDigestOid);
     468    AssertReturn(pDigest, NULL);
     469    AssertReturn(pDigest->enmDigestType != RTDIGESTTYPE_INVALID, NULL);
     470
     471    /* The encryption OID should be a pure encryption algorithm, however we
     472       also accept the already combined algorithm. */
     473    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pEncrypt = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszEncryptionOid);
     474    AssertReturn(pEncrypt, NULL);
     475    uint8_t const idxEncryption = pEncrypt->idxEncryption;
     476    AssertReturn(idxEncryption != IDX_ENCRYPTION_NIL, NULL);
     477    Assert(idxEncryption < RT_ELEMENTS(g_aDigestAndEncryption));
     478
     479    /* Is the encryption OID purely encryption? */
     480    if (pEncrypt->cBitsDigest == 0)
     481    {
     482        Assert(pEncrypt->enmDigestType == RTDIGESTTYPE_INVALID);
     483
     484        /* Identify the slice of the table related to this encryption OID: */
     485        PCRTCRX509ALGORITHIDENTIFIERCOMBINING const paCombinations = g_aDigestAndEncryption[idxEncryption].paCombinations;
     486        size_t                                const cCombinations  = g_aDigestAndEncryption[idxEncryption].cCombinations;
     487
     488        /* Is the digest OID purely a digest? */
     489        if (pDigest->idxEncryption == IDX_ENCRYPTION_NIL)
     490        {
     491            for (size_t i = 0; i < cCombinations; i++)
     492                if (!strcmp(pszDigestOid, paCombinations[i].pszDigestOid))
     493                    return paCombinations[i].pszEncryptedDigestOid;
     494            AssertMsgFailed(("enc=%s hash=%s\n", pszEncryptionOid, pszDigestOid));
     495        }
     496        else
     497        {
     498            /* No, it's a combined one. */
     499            for (size_t i = 0; i < cCombinations; i++)
     500                if (!strcmp(pszDigestOid, paCombinations[i].pszEncryptedDigestOid))
     501                    return paCombinations[i].pszEncryptedDigestOid;
     502            AssertMsgFailed(("enc=%s hash+enc=%s\n", pszEncryptionOid, pszDigestOid));
     503        }
     504    }
     505    /* The digest OID purely a digest? */
     506    else if (pDigest->idxEncryption == IDX_ENCRYPTION_NIL)
     507    {
     508        /* Check that it's for the same hash before returning it. */
     509        Assert(pEncrypt->enmDigestType != RTDIGESTTYPE_INVALID);
     510        if (pEncrypt->enmDigestType == pDigest->enmDigestType)
     511            return pEncrypt->pszSignatureOid;
     512        AssertMsgFailed(("enc+hash=%s hash=%s\n", pszEncryptionOid, pszDigestOid));
     513    }
     514    /* Both the digest and encryption OIDs are combined ones, so they have to
     515       be the same entry then or they cannot be combined. */
     516    else if (pDigest == pEncrypt)
     517        return pEncrypt->pszSignatureOid;
     518    else
     519        AssertMsgFailed(("enc+hash=%s hash+enc=%s\n", pszEncryptionOid, pszDigestOid));
     520
    304521    return NULL;
    305522}
     
    311528    return RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pEncryption->Algorithm.szObjId,
    312529                                                                        pDigest->Algorithm.szObjId);
     530}
     531
     532
     533RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOid(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fMustIncludeHash)
     534{
     535    AssertPtrReturn(pThis, NULL);
     536    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId);
     537    if (pInfo && (!fMustIncludeHash || pInfo->enmDigestType != RTDIGESTTYPE_INVALID))
     538        return g_apszEncryptionOids[pInfo->idxEncryption];
     539    return NULL;
     540}
     541
     542
     543RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(const char *pszAlgorithmOid, bool fMustIncludeHash)
     544{
     545    AssertPtrReturn(pszAlgorithmOid, NULL);
     546    PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszAlgorithmOid);
     547    if (pInfo && (!fMustIncludeHash || pInfo->enmDigestType != RTDIGESTTYPE_INVALID))
     548        return g_apszEncryptionOids[pInfo->idxEncryption];
     549    return NULL;
    313550}
    314551
  • trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp

    r98103 r100442  
    6262    AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_POINTER);
    6363
    64     if (pParameters)
    65     {
    66         AssertPtrReturn(pParameters, VERR_INVALID_POINTER);
    67         if (pParameters->enmType == RTASN1TYPE_NULL)
    68             pParameters = NULL;
    69     }
    70 
    7164    AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER);
    7265    AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_POINTER);
     
    7568     * Check if the algorithm matches.
    7669     */
    77     const char *pszCipherOid = RTCrPkixGetCiperOidFromSignatureAlgorithm(&pThis->SignatureAlgorithm.Algorithm);
     70    const char * const pszCipherOid = RTCrX509AlgorithmIdentifier_GetEncryptionOid(&pThis->SignatureAlgorithm,
     71                                                                                   true /*fMustIncludeHash*/);
    7872    if (!pszCipherOid)
    7973        return RTErrInfoSetF(pErrInfo, VERR_CR_X509_UNKNOWN_CERT_SIGN_ALGO,
     
    9084     */
    9185    RTCRKEY hPubKey;
    92     int rc = RTCrKeyCreateFromPublicAlgorithmAndBits(&hPubKey, pAlgorithm, pPublicKey, pErrInfo, NULL);
     86    int rc = RTCrKeyCreateFromPublicAlgorithmAndBits(&hPubKey, pAlgorithm, pParameters, pPublicKey, pErrInfo, NULL);
    9387    if (RT_FAILURE(rc))
    9488        return rc;
     
    10599    if (RT_SUCCESS(rc))
    106100    {
    107         rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters, &pThis->SignatureValue,
    108                                            pbRaw, cbRaw, pErrInfo);
     101        rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, &pThis->SignatureAlgorithm.Parameters,
     102                                           &pThis->SignatureValue, pbRaw, cbRaw, pErrInfo);
    109103        RTMemTmpFree(pvFree);
    110104    }
     
    127121
    128122    /*
    129      * Assemble parameters for the generic verification call.
     123     * Call generic verification function.
    130124     */
    131     PCRTCRX509TBSCERTIFICATE const pTbsCert    = &pThis->TbsCertificate;
    132     PCRTASN1DYNTYPE                pParameters = NULL;
    133     if (   RTASN1CORE_IS_PRESENT(&pTbsCert->SubjectPublicKeyInfo.Algorithm.Parameters.u.Core)
    134         && pTbsCert->SubjectPublicKeyInfo.Algorithm.Parameters.enmType != RTASN1TYPE_NULL)
    135         pParameters = &pTbsCert->SubjectPublicKeyInfo.Algorithm.Parameters;
    136     return RTCrX509Certificate_VerifySignature(pThis, &pTbsCert->SubjectPublicKeyInfo.Algorithm.Algorithm, pParameters,
     125    PCRTCRX509TBSCERTIFICATE const pTbsCert = &pThis->TbsCertificate;
     126    return RTCrX509Certificate_VerifySignature(pThis,
     127                                               &pTbsCert->SubjectPublicKeyInfo.Algorithm.Algorithm,
     128                                               &pTbsCert->SubjectPublicKeyInfo.Algorithm.Parameters,
    137129                                               &pTbsCert->SubjectPublicKeyInfo.SubjectPublicKey, pErrInfo);
    138130}
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r99669 r100442  
    29402940                    {
    29412941                        PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
    2942                         pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
     2942                        pInfo->enmDigest = RTCrX509AlgorithmIdentifier_GetDigestType(pDigestAlgorithm,
     2943                                                                                     true /*fPureDigestsOnly*/);
    29432944                        AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
    29442945                    }
     
    30113012                {
    30123013                    PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
    3013                     pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
     3014                    pInfo->enmDigest = RTCrX509AlgorithmIdentifier_GetDigestType(pDigestAlgorithm, true /*fPureDigestsOnly*/);
    30143015                    AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
    30153016
  • trunk/src/VBox/Runtime/r3/memsafer-r3.cpp

    r100315 r100442  
    511511    if (pv)
    512512    {
    513         void *pvKey = rtMemSaferScramblePointer(pv);
    514         RTCritSectRwEnterShared(&g_MemSaferCritSect);
    515         PRTMEMSAFERNODE pThis = (PRTMEMSAFERNODE)RTAvlPVGet(&g_pMemSaferTree, pvKey);
    516         if (pThis)
    517             cbRet = pThis->cbUser;
    518         RTCritSectRwLeaveShared(&g_MemSaferCritSect);
     513        /*
     514         * We use this API for testing whether pv is a safer allocation or not,
     515         * so we may be called before the allocators.  Thus, it's prudent to
     516         * make sure initialization has taken place before attempting to enter
     517         * the critical section and such.
     518         */
     519        int rc = RTOnceEx(&g_MemSaferOnce, rtMemSaferOnceInit, rtMemSaferOnceTerm, NULL);
     520        if (RT_SUCCESS(rc))
     521        {
     522            void *pvKey = rtMemSaferScramblePointer(pv);
     523            RTCritSectRwEnterShared(&g_MemSaferCritSect);
     524            PRTMEMSAFERNODE pThis = (PRTMEMSAFERNODE)RTAvlPVGet(&g_pMemSaferTree, pvKey);
     525            if (pThis)
     526                cbRet = pThis->cbUser;
     527            RTCritSectRwLeaveShared(&g_MemSaferCritSect);
     528        }
    519529    }
    520530    return cbRet;
  • trunk/src/VBox/Runtime/tools/Makefile.kmk

    r100006 r100442  
    9999   bldRTSignTool_SOURCES  += \
    100100        ../common/crypto/pkix-signature-builtin.cpp \
     101        ../common/crypto/pkix-signature-ossl.cpp \
    101102        ../common/crypto/store.cpp \
    102103        ../common/crypto/digest-builtin.cpp \
  • trunk/src/VBox/Runtime/tools/RTSignTool.cpp

    r98103 r100442  
    53185318    RTPrintf("%s                     Issuer: %s\n", pThis->szPrefix, pThis->szTmp);
    53195319
    5320     const char *pszType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_QueryDigestType(&pSignerInfo->DigestAlgorithm));
     5320    const char *pszType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_GetDigestType(&pSignerInfo->DigestAlgorithm,
     5321                                                                                         true /*fPureDigestsOnly*/));
    53215322    if (!pszType)
    53225323        pszType = pSignerInfo->DigestAlgorithm.Algorithm.szObjId;
     
    53815382     * The image hash.
    53825383     */
    5383     RTDIGESTTYPE const enmDigestType = RTCrX509AlgorithmIdentifier_QueryDigestType(&pIndData->DigestInfo.DigestAlgorithm);
     5384    RTDIGESTTYPE const enmDigestType = RTCrX509AlgorithmIdentifier_GetDigestType(&pIndData->DigestInfo.DigestAlgorithm,
     5385                                                                                 true /*fPureDigestsOnly*/);
    53845386    const char        *pszDigestType = RTCrDigestTypeToName(enmDigestType);
    53855387    RTPrintf("%s Digest Type: %s", pThis->szPrefix, pszDigestType);
     
    55895591    {
    55905592        PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = pSignedData->DigestAlgorithms.papItems[i];
    5591         const char *pszDigestType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_QueryDigestType(pAlgoId));
     5593        const char *pszDigestType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_GetDigestType(pAlgoId,
     5594                                                                                                   true /*fPureDigestsOnly*/));
    55925595        if (!pszDigestType)
    55935596            pszDigestType = pAlgoId->Algorithm.szObjId;
  • trunk/src/libs/openssl-3.0.7/crypto/asn1/Makefile.kmk

    r98229 r100442  
    6464        bio_asn1.c \
    6565        bio_ndef.c \
     66        d2i_param.c \
    6667        d2i_pr.c \
    6768        d2i_pu.c \
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette