VirtualBox

Changeset 73665 in vbox


Ignore:
Timestamp:
Aug 14, 2018 5:49:23 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124340
Message:

IPRT,SUP,Main: Working on new crypto key handling and rsa signing. bugref:9152

Location:
trunk
Files:
7 added
17 edited

Legend:

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

    r69105 r73665  
    3232RT_C_DECLS_BEGIN
    3333
     34struct RTCRX509SUBJECTPUBLICKEYINFO;
     35
    3436/** @defgroup grp_rt_crpkix RTCrPkix - Public Key Infrastructure APIs
    3537 * @ingroup grp_rt_crypto
     
    4345 * @returns IPRT status code.
    4446 * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
     47 * @param   hPublicKey      The public key.
    4548 * @param   pParameters     Parameter to the public key algorithm. Optional.
    46  * @param   pPublicKey      The public key.
    4749 * @param   pSignatureValue The signature value.
    4850 * @param   pvData          The signed data.
     
    5355 *          performed more than once using all available crypto implementations.
    5456 */
    55 RTDECL(int) RTCrPkixPubKeyVerifySignature(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey,
     57RTDECL(int) RTCrPkixPubKeyVerifySignature(PCRTASN1OBJID pAlgorithm, RTCRKEY hPublicKey, PCRTASN1DYNTYPE pParameters,
    5658                                          PCRTASN1BITSTRING pSignatureValue, const void *pvData, size_t cbData,
    5759                                          PRTERRINFO pErrInfo);
     
    6466 * @returns IPRT status code.
    6567 * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
     68 * @param   hPublicKey      The public key.
    6669 * @param   pParameters     Parameter to the public key algorithm. Optional.
    67  * @param   pPublicKey      The public key.
    6870 * @param   pvSignedDigest  The signed digest.
    6971 * @param   cbSignedDigest  The signed digest size.
     
    7577 *          performed more than once using all available crypto implementations.
    7678 */
    77 RTDECL(int) RTCrPkixPubKeyVerifySignedDigest(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters,
    78                                              PCRTASN1BITSTRING pPublicKey, void const *pvSignedDigest, size_t cbSignedDigest,
     79RTDECL(int) RTCrPkixPubKeyVerifySignedDigest(PCRTASN1OBJID pAlgorithm, RTCRKEY hPublicKey, PCRTASN1DYNTYPE pParameters,
     80                                             void const *pvSignedDigest, size_t cbSignedDigest,
    7981                                             RTCRDIGEST hDigest, PRTERRINFO pErrInfo);
    8082
     83/**
     84 * Wrapper around RTCrPkixPubKeyVerifySignedDigest & RTCrKeyCreateFromAlgorithmAndBits.
     85 *
     86 * @note The public key info must include digest type for this to work.
     87 */
     88RTDECL(int) RTCrPkixPubKeyVerifySignedDigestByCertPubKeyInfo(struct RTCRX509SUBJECTPUBLICKEYINFO const *pCertPubKeyInfo,
     89                                                             void const *pvSignedDigest, size_t cbSignedDigest,
     90                                                             RTCRDIGEST hDigest, PRTERRINFO pErrInfo);
     91
     92
     93/**
     94 * Signs a digest (@a hDigest) using the specified private key (@a pPrivateKey) and algorithm.
     95 *
     96 * @returns IPRT status code.
     97 * @param   pAlgorithm      The signature algorithm (digest w/ cipher).
     98 * @param   hPrivateKey     Handle to the private key to use.
     99 * @param   pParameters     Parameter to the public key algorithm. Optional.
     100 * @param   hDigest         The digest of the data being signed.
     101 * @param   fFlags          Flags for future extensions, MBZ.
     102 * @param   pvSignature     The output signature buffer.  Pass NULL to query
     103 *                          the signature size.
     104 * @param   pcbSignature    On input the variable pointed to holds the size of
     105 *                          the buffer @a pvSignature points to.
     106 *                          On return the variable pointed to is set to the size
     107 *                          of the returned signature, or the required size in
     108 *                          case of VERR_BUFFER_OVERFLOW.
     109 * @param   pErrInfo        Where to return extended error info. Optional.
     110 *
     111 * @remarks Depending on the IPRT build configuration and the algorithm used, the
     112 *          signing may be performed more than once using all available crypto
     113 *          implementations.
     114 */
     115RTDECL(int) RTCrPkixPubKeySignDigest(PCRTASN1OBJID pAlgorithm, RTCRKEY hPrivateKey, PCRTASN1DYNTYPE pParameters,
     116                                     RTCRDIGEST hDigest, uint32_t fFlags,
     117                                     void *pvSignature, size_t *pcbSignature, PRTERRINFO pErrInfo);
    81118
    82119/**
     
    141178     *                          setting for the lifetime of the instance due to the
    142179     *                          algorithm requiring different keys.
    143      * @param   pKey            The key to use (whether private or public depends on
    144      *                          the operation).
     180     * @param   hKey            The key handle.  Caller has retained it for the
     181     *                          lifetime of the state being initialize.
    145182     * @param   pParams         Algorithm/key parameters, optional.  Will be NULL if
    146183     *                          none.
    147184     */
    148185    DECLCALLBACKMEMBER(int, pfnInit)(struct RTCRPKIXSIGNATUREDESC const *pDesc, void *pvState, void *pvOpaque, bool fSigning,
    149                                      PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams);
     186                                     RTCRKEY hKey, PCRTASN1DYNTYPE pParams);
    150187
    151188    /**
     
    183220     * @param   pDesc           Pointer to this structure (for uProviderSpecific).
    184221     * @param   pvState         The opaque provider state.
     222     * @param   hKey            The key handle associated with the state at init.
    185223     * @param   hDigest         The handle to the digest.  Call RTCrDigestFinal to
    186224     *                          complete and retreive the final hash value.
     
    188226     * @param   cbSignature     The size of the signature (in bytes).
    189227     */
    190     DECLCALLBACKMEMBER(int, pfnVerify)(struct RTCRPKIXSIGNATUREDESC const *pDesc, void *pvState,
     228    DECLCALLBACKMEMBER(int, pfnVerify)(struct RTCRPKIXSIGNATUREDESC const *pDesc, void *pvState, RTCRKEY hKey,
    191229                                       RTCRDIGEST hDigest, void const *pvSignature, size_t cbSignature);
    192230
     
    202240     * @param   pDesc           Pointer to this structure (for uProviderSpecific).
    203241     * @param   pvState         The opaque provider state.
     242     * @param   hKey            The key handle associated with the state at init.
    204243     * @param   hDigest         The handle to the digest.  Call RTCrDigestFinal to
    205244     *                          complete and retreive the final hash value.
     
    211250     *                          case of VERR_BUFFER_OVERFLOW.
    212251     */
    213     DECLCALLBACKMEMBER(int, pfnSign)(struct RTCRPKIXSIGNATUREDESC const *pDesc, void *pvState,
     252    DECLCALLBACKMEMBER(int, pfnSign)(struct RTCRPKIXSIGNATUREDESC const *pDesc, void *pvState, RTCRKEY hKey,
    214253                                     RTCRDIGEST hDigest, void *pvSignature, size_t *pcbSignature);
    215254
     
    220259
    221260PCRTCRPKIXSIGNATUREDESC RTCrPkixSignatureFindByObjIdString(const char *pszObjId, void *ppvOpaque);
    222 PCRTCRPKIXSIGNATUREDESC RTCrPkixSignatureFindByObjId(PCRTASN1OBJID pObjId, void *ppvOpaque);
     261PCRTCRPKIXSIGNATUREDESC RTCrPkixSignatureFindByObjId(PCRTASN1OBJID pObjId, void **ppvOpaque);
    223262RTDECL(int) RTCrPkixSignatureCreateByObjIdString(PRTCRPKIXSIGNATURE phSignature, const char *pszObjId, bool fSigning,
    224                                                  PCRTASN1BITSTRING pKey,PCRTASN1DYNTYPE pParams);
    225 RTDECL(int) RTCrPkixSignatureCreateByObjId(PRTCRPKIXSIGNATURE phSignature, PCRTASN1OBJID pObjId, bool fSigning,
    226                                            PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams);
     263                                                 RTCRKEY hKey, PCRTASN1DYNTYPE pParams);
     264RTDECL(int) RTCrPkixSignatureCreateByObjId(PRTCRPKIXSIGNATURE phSignature, PCRTASN1OBJID pObjId, RTCRKEY hKey,
     265                                           PCRTASN1DYNTYPE pParams, bool fSigning);
    227266
    228267
    229268RTDECL(int) RTCrPkixSignatureCreate(PRTCRPKIXSIGNATURE phSignature, PCRTCRPKIXSIGNATUREDESC pDesc, void *pvOpaque,
    230                                     bool fSigning, PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams);
     269                                    bool fSigning, RTCRKEY hKey, PCRTASN1DYNTYPE pParams);
    231270RTDECL(uint32_t) RTCrPkixSignatureRetain(RTCRPKIXSIGNATURE hSignature);
    232271RTDECL(uint32_t) RTCrPkixSignatureRelease(RTCRPKIXSIGNATURE hSignature);
  • trunk/include/iprt/err.h

    r73494 r73665  
    27292729/** The EVP_PKEY_type API in OpenSSL failed.  */
    27302730#define VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR       (-23517)
     2731/** OpenSSL failed to decode the public key. */
     2732#define VERR_CR_PKIX_OSSL_D2I_PRIVATE_KEY_FAILED    (-23518)
     2733/** The EVP_PKEY_CTX_set_rsa_padding API in OpenSSL failed.  */
     2734#define VERR_CR_PKIX_OSSL_EVP_PKEY_RSA_PAD_ERROR    (-23519)
     2735/** Final OpenSSL PKIX signing failed. */
     2736#define VERR_CR_PKIX_OSSL_SIGN_FINAL_FAILED         (-23520)
     2737/** OpenSSL and IPRT disagree on the signature size. */
     2738#define VERR_CR_PKIX_OSSL_VS_IPRT_SIGNATURE_SIZE    (-23521)
     2739/** OpenSSL and IPRT disagree on the signature. */
     2740#define VERR_CR_PKIX_OSSL_VS_IPRT_SIGNATURE         (-23522)
     2741/** Expected RSA private key. */
     2742#define VERR_CR_PKIX_NOT_RSA_PRIVATE_KEY            (-23523)
     2743/** Expected RSA public key. */
     2744#define VERR_CR_PKIX_NOT_RSA_PUBLIC_KEY             (-23524)
    27312745/** @} */
    27322746
     
    27352749/** Generic store error. */
    27362750#define VERR_CR_STORE_GENERIC_ERROR                 (-23700)
     2751/** @} */
     2752
     2753/** @name RTCrKey status codes.
     2754 * @{ */
     2755/** Could not recognize the key type. */
     2756#define VERR_CR_KEY_UNKNOWN_TYPE                    (-23800)
     2757/** Unsupported key format. */
     2758#define VERR_CR_KEY_FORMAT_NOT_SUPPORTED            (-23801)
    27372759/** @} */
    27382760
  • trunk/include/iprt/mangling.h

    r73662 r73665  
    31113111# define RTCrDigestTypeToName                           RT_MANGLER(RTCrDigestTypeToName)
    31123112# define RTCrDigestTypeToHashSize                       RT_MANGLER(RTCrDigestTypeToHashSize)
     3113# define RTCrKeyCreateFromBuffer                        RT_MANGLER(RTCrKeyCreateFromBuffer)
     3114# define RTCrKeyCreateFromFile                          RT_MANGLER(RTCrKeyCreateFromFile)
     3115# define RTCrKeyCreateFromPemSection                    RT_MANGLER(RTCrKeyCreateFromPemSection)
     3116# define RTCrKeyCreateFromPublicAlgorithmAndBits        RT_MANGLER(RTCrKeyCreateFromPublicAlgorithmAndBits)
     3117# define RTCrKeyCreateFromSubjectPublicKeyInfo          RT_MANGLER(RTCrKeyCreateFromSubjectPublicKeyInfo)
     3118# define RTCrKeyGetBitCount                             RT_MANGLER(RTCrKeyGetBitCount)
     3119# define RTCrKeyGetType                                 RT_MANGLER(RTCrKeyGetType)
     3120# define RTCrKeyHasPrivatePart                          RT_MANGLER(RTCrKeyHasPrivatePart)
     3121# define RTCrKeyHasPublicPart                           RT_MANGLER(RTCrKeyHasPublicPart)
     3122# define RTCrKeyRelease                                 RT_MANGLER(RTCrKeyRelease)
     3123# define RTCrKeyRetain                                  RT_MANGLER(RTCrKeyRetain)
    31133124# define RTCrRsaDigestInfo_DecodeAsn1                   RT_MANGLER(RTCrRsaDigestInfo_DecodeAsn1)
    31143125# define RTCrRsaOtherPrimeInfo_DecodeAsn1               RT_MANGLER(RTCrRsaOtherPrimeInfo_DecodeAsn1)
  • trunk/include/iprt/types.h

    r73475 r73665  
    20872087#define NIL_RTCRDIGEST                              (0)
    20882088
     2089/** Cryptographic key handle. */
     2090typedef R3R0PTRTYPE(struct RTCRKEYINT RT_FAR *)     RTCRKEY;
     2091/** Pointer to a cryptographic key handle. */
     2092typedef RTCRKEY                             RT_FAR *PRTCRKEY;
     2093/** Cryptographic key handle nil value. */
     2094#define NIL_RTCRKEY                                 (0)
     2095
    20892096/** Public key encryption schema handle. */
    20902097typedef R3R0PTRTYPE(struct RTCRPKIXENCRYPTIONINT RT_FAR *) RTCRPKIXENCRYPTION;
  • trunk/src/VBox/HostDrivers/Support/Makefile.kmk

    r72247 r73665  
    242242        $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-cursor.cpp \
    243243        $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-default-allocator.cpp \
     244        $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-safer-allocator.cpp \
    244245        $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-dump.cpp \
    245246        $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-encode.cpp \
     
    266267        $(VBOX_PATH_RUNTIME_SRC)/common/crypto/digest-core.cpp \
    267268        $(VBOX_PATH_RUNTIME_SRC)/common/crypto/digest-builtin.cpp \
     269        $(VBOX_PATH_RUNTIME_SRC)/common/crypto/key.cpp \
    268270        $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-asn1-decoder.cpp \
    269271        $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-core.cpp \
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r73132 r73665  
    17291729                   API will do the verification twice, once using IPRT's own crypto
    17301730                   and once using OpenSSL.  Both must OK it for success.) */
    1731                 vrc = RTCrPkixPubKeyVerifySignedDigest(&m->SignerCert.TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm,
    1732                                                        &m->SignerCert.TbsCertificate.SubjectPublicKeyInfo.Algorithm.Parameters,
    1733                                                        &m->SignerCert.TbsCertificate.SubjectPublicKeyInfo.SubjectPublicKey,
    1734                                                        m->pbSignedDigest, m->cbSignedDigest, hDigest,
    1735                                                        RTErrInfoInitStatic(&StaticErrInfo));
     1731                vrc = RTCrPkixPubKeyVerifySignedDigestByCertPubKeyInfo(&m->SignerCert.TbsCertificate.SubjectPublicKeyInfo,
     1732                                                                       m->pbSignedDigest, m->cbSignedDigest, hDigest,
     1733                                                                       RTErrInfoInitStatic(&StaticErrInfo));
    17361734                if (RT_SUCCESS(vrc))
    17371735                {
  • trunk/src/VBox/Runtime/Makefile.kmk

    r73098 r73665  
    314314        common/asn1/asn1-default-allocator.cpp \
    315315        common/asn1/asn1-efence-allocator.cpp \
     316        common/asn1/asn1-safer-allocator.cpp \
    316317        common/asn1/asn1-dump.cpp \
    317318        common/asn1/asn1-encode.cpp \
     
    367368        common/crypto/digest-vfs.cpp \
    368369        common/crypto/iprt-openssl.cpp \
     370        common/crypto/key.cpp \
     371        common/crypto/key-file.cpp \
     372        common/crypto/key-openssl.cpp \
    369373        common/crypto/rsa-asn1-decoder.cpp \
    370374        common/crypto/rsa-core.cpp \
     
    377381        common/crypto/pkcs7-sanity.cpp \
    378382        common/crypto/pkcs7-verify.cpp \
     383        common/crypto/pkix-sign.cpp \
    379384        common/crypto/pkix-signature-builtin.cpp \
    380385        common/crypto/pkix-signature-core.cpp \
     
    23042309        common/asn1/asn1-cursor.cpp \
    23052310        common/asn1/asn1-default-allocator.cpp \
     2311        common/asn1/asn1-safer-allocator.cpp \
    23062312        common/asn1/asn1-encode.cpp \
    23072313        common/asn1/asn1-ut-bitstring.cpp \
     
    23272333        common/crypto/digest-core.cpp \
    23282334        common/crypto/digest-builtin.cpp \
     2335        common/crypto/key.cpp \
    23292336        common/crypto/rsa-asn1-decoder.cpp \
    23302337        common/crypto/rsa-core.cpp \
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp

    r69111 r73665  
    3535#include <iprt/string.h>
    3636#include <iprt/crypto/digest.h>
     37#include <iprt/crypto/key.h>
    3738#include <iprt/crypto/pkix.h>
    3839#include <iprt/crypto/store.h>
     
    477478        if (RT_SUCCESS(rc))
    478479        {
    479             RTCRPKIXSIGNATURE hSignature;
    480             rc = RTCrPkixSignatureCreateByObjId(&hSignature,
    481                                                 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm,
    482                                                 false /*fSigning*/,
    483                                                 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.SubjectPublicKey,
    484                                                 &pSignerInfo->DigestEncryptionAlgorithm.Parameters);
     480            RTCRKEY hKey;
     481            rc = RTCrKeyCreateFromSubjectPublicKeyInfo(&hKey, &pSignerCert->TbsCertificate.SubjectPublicKeyInfo,
     482                                                       pErrInfo, "pkcs7");
    485483            if (RT_SUCCESS(rc))
    486484            {
    487                 /** @todo Check that DigestEncryptionAlgorithm is compatible with hSignature
    488                  *        (this is not vital). */
    489                 rc = RTCrPkixSignatureVerifyOctetString(hSignature, hDigest, &pSignerInfo->EncryptedDigest);
    490                 if (RT_FAILURE(rc))
    491                     rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNATURE_VERIFICATION_FAILED,
    492                                        "Signature verficiation failed: %Rrc", rc);
    493                 RTCrPkixSignatureRelease(hSignature);
     485                RTCRPKIXSIGNATURE hSignature;
     486                rc = RTCrPkixSignatureCreateByObjId(&hSignature, &pSignerInfo->DigestEncryptionAlgorithm.Algorithm,
     487                                                    hKey, &pSignerInfo->DigestEncryptionAlgorithm.Parameters, false /*fSigning*/);
     488                RTCrKeyRelease(hKey);
     489                if (RT_SUCCESS(rc))
     490                {
     491                    /** @todo Check that DigestEncryptionAlgorithm is compatible with hSignature
     492                     *        (this is not vital). */
     493                    rc = RTCrPkixSignatureVerifyOctetString(hSignature, hDigest, &pSignerInfo->EncryptedDigest);
     494                    if (RT_FAILURE(rc))
     495                        rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNATURE_VERIFICATION_FAILED,
     496                                           "Signature verficiation failed: %Rrc", rc);
     497                    RTCrPkixSignatureRelease(hSignature);
     498                }
     499                else
     500                    rc = RTErrInfoSetF(pErrInfo, rc, "Failure to instantiate public key algorithm [IPRT]: %s (%s)",
     501                                       pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId,
     502                                       pSignerInfo->DigestEncryptionAlgorithm.Algorithm.szObjId);
    494503            }
    495             else
    496                 rc = RTErrInfoSetF(pErrInfo, rc, "Failure to instantiate public key algorithm [IPRT]: %s (%s)",
    497                                    pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId,
    498                                    pSignerInfo->DigestEncryptionAlgorithm.Algorithm.szObjId);
    499504        }
    500505
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-builtin.cpp

    r69111 r73665  
    116116
    117117
    118 RTDECL(int) RTCrPkixSignatureCreateByObjIdString(PRTCRPKIXSIGNATURE phSignature, const char *pszObjId, bool fSigning,
    119                                                  PCRTASN1BITSTRING pKey,PCRTASN1DYNTYPE pParams)
     118RTDECL(int) RTCrPkixSignatureCreateByObjIdString(PRTCRPKIXSIGNATURE phSignature, const char *pszObjId,
     119                                                 RTCRKEY hKey, PCRTASN1DYNTYPE pParams, bool fSigning)
    120120{
    121121    void *pvOpaque;
    122122    PCRTCRPKIXSIGNATUREDESC pDesc = RTCrPkixSignatureFindByObjIdString(pszObjId, &pvOpaque);
    123123    if (pDesc)
    124         return RTCrPkixSignatureCreate(phSignature, pDesc, pvOpaque, fSigning, pKey, pParams);
     124        return RTCrPkixSignatureCreate(phSignature, pDesc, pvOpaque, fSigning, hKey, pParams);
    125125    return VERR_NOT_FOUND;
    126126}
    127127
    128128
    129 RTDECL(int) RTCrPkixSignatureCreateByObjId(PRTCRPKIXSIGNATURE phSignature, PCRTASN1OBJID pObjId, bool fSigning,
    130                                            PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams)
     129RTDECL(int) RTCrPkixSignatureCreateByObjId(PRTCRPKIXSIGNATURE phSignature, PCRTASN1OBJID pObjId,
     130                                           RTCRKEY hKey, PCRTASN1DYNTYPE pParams, bool fSigning)
    131131{
    132132    void *pvOpaque;
    133133    PCRTCRPKIXSIGNATUREDESC pDesc = RTCrPkixSignatureFindByObjId(pObjId, &pvOpaque);
    134134    if (pDesc)
    135         return RTCrPkixSignatureCreate(phSignature, pDesc, pvOpaque, fSigning, pKey, pParams);
     135        return RTCrPkixSignatureCreate(phSignature, pDesc, pvOpaque, fSigning, hKey, pParams);
    136136    return VERR_NOT_FOUND;
    137137}
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-core.cpp

    r73097 r73665  
    3838#include <iprt/string.h>
    3939#include <iprt/crypto/digest.h>
     40#include <iprt/crypto/key.h>
    4041
    4142
     
    5455    /** Pointer to the message digest descriptor. */
    5556    PCRTCRPKIXSIGNATUREDESC pDesc;
     57    /** Key being used (referrenced of course). */
     58    RTCRKEY                 hKey;
    5659    /** The operation this instance is licensed for. */
    5760    bool                    fSigning;
    5861    /** State. */
    5962    uint32_t                uState;
    60 #if ARCH_BITS == 32
    61     uint32_t                uPadding;
    62 #endif
    6363
    6464    /** Opaque data specific to the message digest algorithm, size given by
     
    8686
    8787RTDECL(int) RTCrPkixSignatureCreate(PRTCRPKIXSIGNATURE phSignature, PCRTCRPKIXSIGNATUREDESC pDesc, void *pvOpaque,
    88                                     bool fSigning, PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams)
     88                                    bool fSigning, RTCRKEY hKey, PCRTASN1DYNTYPE pParams)
    8989{
    9090    /*
     
    9393    AssertPtrReturn(phSignature, VERR_INVALID_POINTER);
    9494    AssertPtrReturn(pDesc, VERR_INVALID_POINTER);
    95     AssertPtrReturn(pKey, VERR_INVALID_POINTER);
    96     AssertReturn(RTAsn1BitString_IsPresent(pKey), VERR_INVALID_PARAMETER);
    9795    if (pParams)
    9896    {
     
    102100            pParams = NULL;
    103101    }
     102    uint32_t cKeyRefs = RTCrKeyRetain(hKey);
     103    AssertReturn(cKeyRefs != UINT32_MAX, VERR_INVALID_HANDLE);
    104104
    105105    /*
     
    116116        pThis->fSigning     = fSigning;
    117117        pThis->uState       = RTCRPKIXSIGNATURE_STATE_READY;
     118        pThis->hKey         = hKey;
    118119        if (pDesc->pfnInit)
    119             rc = pDesc->pfnInit(pDesc, pThis->abState, pvOpaque, fSigning, pKey, pParams);
     120            rc = pDesc->pfnInit(pDesc, pThis->abState, pvOpaque, fSigning, hKey, pParams);
    120121        if (RT_SUCCESS(rc))
    121122        {
     
    128129    else
    129130        rc = VERR_NO_MEMORY;
     131    RTCrKeyRelease(hKey);
    130132    return rc;
    131133
     
    142144    Assert(cRefs < 64);
    143145    return cRefs;
     146}
     147
     148
     149/**
     150 * Destructor worker.
     151 */
     152static uint32_t rtCrPkixSignatureDestructor(PRTCRPKIXSIGNATUREINT pThis)
     153{
     154    pThis->u32Magic = ~RTCRPKIXSIGNATUREINT_MAGIC;
     155    if (pThis->pDesc->pfnDelete)
     156        pThis->pDesc->pfnDelete(pThis->pDesc, pThis->abState, pThis->fSigning);
     157
     158    RTCrKeyRelease(pThis->hKey);
     159    pThis->hKey = NIL_RTCRKEY;
     160
     161    size_t cbToWipe = RT_UOFFSETOF_DYN(RTCRPKIXSIGNATUREINT, abState[pThis->pDesc->cbState]);
     162    RTMemWipeThoroughly(pThis, cbToWipe, 6);
     163
     164    RTMemFree(pThis);
     165    return 0;
    144166}
    145167
     
    156178    Assert(cRefs < 64);
    157179    if (!cRefs)
    158     {
    159         pThis->u32Magic = ~RTCRPKIXSIGNATUREINT_MAGIC;
    160         if (pThis->pDesc->pfnDelete)
    161             pThis->pDesc->pfnDelete(pThis->pDesc, pThis->abState, pThis->fSigning);
    162 
    163         size_t cbToWipe = RT_UOFFSETOF_DYN(RTCRPKIXSIGNATUREINT, abState[pThis->pDesc->cbState]);
    164         RTMemWipeThoroughly(pThis, cbToWipe, 6);
    165 
    166         RTMemFree(pThis);
    167     }
     180        return rtCrPkixSignatureDestructor(pThis);
    168181    return cRefs;
    169182}
     
    211224    if (RT_SUCCESS(rc))
    212225    {
    213         rc = pThis->pDesc->pfnVerify(pThis->pDesc, pThis->abState, hDigest, pvSignature, cbSignature);
     226        rc = pThis->pDesc->pfnVerify(pThis->pDesc, pThis->abState, pThis->hKey, hDigest, pvSignature, cbSignature);
    214227        pThis->uState = RTCRPKIXSIGNATURE_STATE_DONE;
    215228    }
     
    265278    if (RT_SUCCESS(rc))
    266279    {
    267         rc = pThis->pDesc->pfnSign(pThis->pDesc, pThis->abState, hDigest, pvSignature, pcbSignature);
     280        rc = pThis->pDesc->pfnSign(pThis->pDesc, pThis->abState, pThis->hKey, hDigest, pvSignature, pcbSignature);
    268281        if (rc != VERR_BUFFER_OVERFLOW)
    269282            pThis->uState = RTCRPKIXSIGNATURE_STATE_DONE;
  • trunk/src/VBox/Runtime/common/crypto/pkix-signature-rsa.cpp

    r69111 r73665  
    4141#include "rsa-internal.h"
    4242#include "pkix-signature-builtin.h"
     43#include "key-internal.h"
    4344
    4445
     
    5354    /** Set if we're signing, clear if verifying.  */
    5455    bool                    fSigning;
    55     /** The modulus.  */
    56     RTBIGNUM                Modulus;
    57     /** The exponent.  */
    58     RTBIGNUM                Exponent;
    5956
    6057    /** Temporary big number for use when signing or verifiying. */
     
    138135/** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnInit}  */
    139136static DECLCALLBACK(int) rtCrPkixSignatureRsa_Init(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, void *pvOpaque,
    140                                                    bool fSigning, PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams)
     137                                                   bool fSigning, RTCRKEY hKey, PCRTASN1DYNTYPE pParams)
    141138{
    142139    RT_NOREF_PV(pDesc); RT_NOREF_PV(pvState); RT_NOREF_PV(pvOpaque);
     
    145142        return VERR_CR_PKIX_SIGNATURE_TAKES_NO_PARAMETERS;
    146143
     144    RTCRKEYTYPE enmKeyType = RTCrKeyGetType(hKey);
     145    if (fSigning)
     146        AssertReturn(enmKeyType == RTCRKEYTYPE_RSA_PRIVATE, VERR_CR_PKIX_NOT_RSA_PRIVATE_KEY);
     147    else
     148        AssertReturn(enmKeyType == RTCRKEYTYPE_RSA_PUBLIC, VERR_CR_PKIX_NOT_RSA_PUBLIC_KEY);
     149
    147150    PRTCRPKIXSIGNATURERSA pThis = (PRTCRPKIXSIGNATURERSA)pvState;
    148151    pThis->fSigning = fSigning;
    149152
    150     /*
    151      * Decode the key and pick the bits we really need from it.
    152      */
    153     RTASN1CURSORPRIMARY PrimaryCursor;
    154     RTAsn1CursorInitPrimary(&PrimaryCursor, RTASN1BITSTRING_GET_BIT0_PTR(pKey), RTASN1BITSTRING_GET_BYTE_SIZE(pKey),
    155                             NULL, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, "rsa");
    156     int rc;
    157     if (!fSigning)
    158     {
    159         rc = RTCrRsaPublicKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pThis->Scratch.PublicKey, "PublicKey");
    160         if (RT_SUCCESS(rc))
    161         {
    162             rc = RTAsn1Integer_ToBigNum(&pThis->Scratch.PublicKey.Modulus, &pThis->Modulus, 0);
    163             if (RT_SUCCESS(rc))
    164             {
    165                 rc = RTAsn1Integer_ToBigNum(&pThis->Scratch.PublicKey.PublicExponent, &pThis->Exponent, 0);
    166                 if (RT_SUCCESS(rc))
    167                 {
    168                     RTAsn1VtDelete(&pThis->Scratch.PublicKey.SeqCore.Asn1Core);
    169                     return VINF_SUCCESS;
    170                 }
    171                 RTBigNumDestroy(&pThis->Modulus);
    172             }
    173             RTAsn1VtDelete(&pThis->Scratch.PublicKey.SeqCore.Asn1Core);
    174         }
    175     }
    176     else
    177     {
    178         rc = RTCrRsaPrivateKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pThis->Scratch.PrivateKey, "PrivateKey");
    179         if (RT_SUCCESS(rc))
    180         {
    181             rc = RTAsn1Integer_ToBigNum(&pThis->Scratch.PrivateKey.Modulus, &pThis->Modulus, RTBIGNUMINIT_F_SENSITIVE);
    182             if (RT_SUCCESS(rc))
    183             {
    184                 rc = RTAsn1Integer_ToBigNum(&pThis->Scratch.PrivateKey.PublicExponent, &pThis->Exponent, RTBIGNUMINIT_F_SENSITIVE);
    185                 if (RT_SUCCESS(rc))
    186                 {
    187                     RTAsn1VtDelete(&pThis->Scratch.PrivateKey.SeqCore.Asn1Core);
    188                     return VINF_SUCCESS;
    189                 }
    190                 RTBigNumDestroy(&pThis->Modulus);
    191             }
    192             RTAsn1VtDelete(&pThis->Scratch.PrivateKey.SeqCore.Asn1Core);
    193         }
    194     }
    195     return rc;
     153    return VINF_SUCCESS;
    196154}
    197155
     
    213171    RT_NOREF_PV(fSigning); RT_NOREF_PV(pDesc);
    214172    Assert(pThis->fSigning == fSigning);
    215 
    216     RTBigNumDestroy(&pThis->Modulus);
    217     RTBigNumDestroy(&pThis->Exponent);
    218173}
    219174
     
    246201     * Figure out which hash and select the associate prebaked DigestInfo.
    247202     */
    248     RTDIGESTTYPE const  enmDigest    = RTCrDigestGetType(hDigest);
     203    RTDIGESTTYPE const  enmDigest = RTCrDigestGetType(hDigest);
    249204    AssertReturn(enmDigest != RTDIGESTTYPE_INVALID && enmDigest != RTDIGESTTYPE_UNKNOWN, VERR_CR_PKIX_UNKNOWN_DIGEST_TYPE);
    250205    uint8_t const      *pbDigestInfoStart = NULL;
     
    297252
    298253/** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnVerify}  */
    299 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Verify(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState,
     254static DECLCALLBACK(int) rtCrPkixSignatureRsa_Verify(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, RTCRKEY hKey,
    300255                                                     RTCRDIGEST hDigest, void const *pvSignature, size_t cbSignature)
    301256{
     
    307262
    308263    /*
    309      * 8.2.2.1 - Length check.
    310      */
    311     if (cbSignature != RTBigNumByteWidth(&pThis->Modulus))
     264     * Get the key bits we need.
     265     */
     266    Assert(RTCrKeyGetType(hKey) == RTCRKEYTYPE_RSA_PUBLIC);
     267    PRTBIGNUM pModulus  = &hKey->u.RsaPublic.Modulus;
     268    PRTBIGNUM pExponent = &hKey->u.RsaPublic.Exponent;
     269
     270    /*
     271     * 8.2.2.1 - Length check.  (RFC-3447)
     272     */
     273    if (cbSignature != RTBigNumByteWidth(pModulus))
    312274        return VERR_CR_PKIX_INVALID_SIGNATURE_LENGTH;
    313275
     
    321283        return rc;
    322284    /* b) RSAVP1 - 5.2.2.2: Range check (0 <= s < n). */
    323     if (RTBigNumCompare(&pThis->TmpBigNum1, &pThis->Modulus) < 0)
     285    if (RTBigNumCompare(&pThis->TmpBigNum1, pModulus) < 0)
    324286    {
    325287        if (RTBigNumCompareWithU64(&pThis->TmpBigNum1, 0) >= 0)
     
    329291            if (RT_SUCCESS(rc))
    330292            {
    331                 rc = RTBigNumModExp(&pThis->TmpBigNum2, &pThis->TmpBigNum1, &pThis->Exponent, &pThis->Modulus);
     293                rc = RTBigNumModExp(&pThis->TmpBigNum2, &pThis->TmpBigNum1, pExponent, pModulus);
    332294                if (RT_SUCCESS(rc))
    333295                {
     
    387349
    388350/** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnSign}  */
    389 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Sign(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState,
     351static DECLCALLBACK(int) rtCrPkixSignatureRsa_Sign(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, RTCRKEY hKey,
    390352                                                   RTCRDIGEST hDigest, void *pvSignature, size_t *pcbSignature)
    391353{
    392354    PRTCRPKIXSIGNATURERSA pThis = (PRTCRPKIXSIGNATURERSA)pvState;
    393     RT_NOREF_PV(pDesc);  RT_NOREF_PV(hDigest); RT_NOREF_PV(pvSignature); RT_NOREF_PV(pcbSignature);
    394     Assert(pThis->fSigning); NOREF(pThis);
    395     return VERR_NOT_IMPLEMENTED;
     355    RT_NOREF_PV(pDesc);
     356    Assert(pThis->fSigning);
     357
     358    /*
     359     * Get the key bits we need.
     360     */
     361    Assert(RTCrKeyGetType(hKey) == RTCRKEYTYPE_RSA_PRIVATE);
     362    PRTBIGNUM pModulus  = &hKey->u.RsaPrivate.Modulus;
     363    PRTBIGNUM pExponent = &hKey->u.RsaPrivate.PrivateExponent;
     364
     365    /*
     366     * Calc signature length and return if destination buffer isn't big enough.
     367     */
     368    size_t const cbDst        = *pcbSignature;
     369    size_t const cbEncodedMsg = RTBigNumByteWidth(pModulus);
     370    *pcbSignature = cbEncodedMsg;
     371    if (cbEncodedMsg > sizeof(pThis->Scratch) / 2)
     372        return VERR_CR_PKIX_SIGNATURE_TOO_LONG;
     373    if (!pvSignature || cbDst < cbEncodedMsg)
     374        return VERR_BUFFER_OVERFLOW;
     375
     376    /*
     377     * 8.1.1.1 - EMSA-PSS encoding.  (RFC-3447)
     378     */
     379    int rc = rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(pThis, hDigest, cbEncodedMsg, false /* fNoDigestInfo */);
     380    if (RT_FAILURE(rc))
     381        return rc;
     382
     383    /*
     384     * 8.1.1.2 - RSA signature.
     385     */
     386    /* a) m = OS2IP(EM) -- Convert the encoded message (EM) to integer. */
     387    rc = RTBigNumInit(&pThis->TmpBigNum1, RTBIGNUMINIT_F_ENDIAN_BIG | RTBIGNUMINIT_F_UNSIGNED,
     388                      pThis->Scratch.abSignature, cbEncodedMsg);
     389    if (RT_FAILURE(rc))
     390        return rc;
     391
     392    /* b) s = RSASP1(K, m = EM) - 5.2.1.1: Range check (0 <= m < n). */
     393    if (RTBigNumCompare(&pThis->TmpBigNum1, pModulus) < 0)
     394    {
     395        /* b) s = RSAVP1(K, m = EM) - 5.2.1.2.a: s = m^d mod n */
     396        rc = RTBigNumInitZero(&pThis->TmpBigNum2, 0);
     397        if (RT_SUCCESS(rc))
     398        {
     399            rc = RTBigNumModExp(&pThis->TmpBigNum2, &pThis->TmpBigNum1, pExponent, pModulus);
     400            if (RT_SUCCESS(rc))
     401            {
     402                /* c) S = I2OSP(s, k) -- Convert the result to bytes. */
     403                rc = RTBigNumToBytesBigEndian(&pThis->TmpBigNum2, pvSignature, cbEncodedMsg);
     404                AssertStmt(RT_SUCCESS(rc) || rc != VERR_BUFFER_OVERFLOW, rc = VERR_CR_PKIX_INTERNAL_ERROR);
     405            }
     406            RTBigNumDestroy(&pThis->TmpBigNum2);
     407        }
     408    }
     409    else
     410        rc = VERR_CR_PKIX_SIGNATURE_GE_KEY;
     411    RTBigNumDestroy(&pThis->TmpBigNum1);
     412    return rc;
    396413}
    397414
  • trunk/src/VBox/Runtime/common/crypto/pkix-verify.cpp

    r69111 r73665  
    3535#include <iprt/string.h>
    3636#include <iprt/crypto/digest.h>
     37#include <iprt/crypto/key.h>
    3738
    3839#ifdef IPRT_WITH_OPENSSL
     
    4546
    4647
    47 RTDECL(int) RTCrPkixPubKeyVerifySignature(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey,
     48
     49RTDECL(int) RTCrPkixPubKeyVerifySignature(PCRTASN1OBJID pAlgorithm, RTCRKEY hPublicKey, PCRTASN1DYNTYPE pParameters,
    4850                                          PCRTASN1BITSTRING pSignatureValue, const void *pvData, size_t cbData,
    4951                                          PRTERRINFO pErrInfo)
     
    6264    }
    6365
    64     AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER);
    65     AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_POINTER);
     66    AssertPtrReturn(hPublicKey, VERR_INVALID_POINTER);
     67    Assert(RTCrKeyHasPublicPart(hPublicKey));
    6668
    6769    AssertPtrReturn(pSignatureValue, VERR_INVALID_POINTER);
     
    8284     */
    8385    RTCRPKIXSIGNATURE hSignature;
    84     int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, false /*fSigning*/, pPublicKey, pParameters);
     86    int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
    8587    if (RT_FAILURE(rcIprt))
    8688        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
     
    111113     * Validate using OpenSSL EVP.
    112114     */
    113     rtCrOpenSslInit();
    114 
    115     /* Translate the algorithm ID into a EVP message digest type pointer. */
    116     int iAlgoNid = OBJ_txt2nid(pAlgorithm->szObjId);
    117     if (iAlgoNid == NID_undef)
    118         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN,
    119                              "Unknown public key algorithm [OpenSSL]: %s", pAlgorithm->szObjId);
    120     const char *pszAlgoSn = OBJ_nid2sn(iAlgoNid);
    121 
    122 # if OPENSSL_VERSION_NUMBER >= 0x10001000 && !defined(LIBRESSL_VERSION_NUMBER)
    123     int idAlgoPkey = 0;
    124     int idAlgoMd = 0;
    125     if (!OBJ_find_sigid_algs(iAlgoNid, &idAlgoMd, &idAlgoPkey))
    126         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    127                              "OBJ_find_sigid_algs failed on %u (%s, %s)", iAlgoNid, pszAlgoSn, pAlgorithm->szObjId);
    128     const EVP_MD *pEvpMdType = EVP_get_digestbynid(idAlgoMd);
    129     if (!pEvpMdType)
    130         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    131                              "EVP_get_digestbynid failed on %d (%s, %s)", idAlgoMd, pszAlgoSn, pAlgorithm->szObjId);
    132 # else
    133     const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlgoSn);
    134     if (!pEvpMdType)
    135         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    136                              "EVP_get_digestbyname failed on %s (%s)", pszAlgoSn, pAlgorithm->szObjId);
    137 # endif
    138 
    139     EVP_MD_CTX *pEvpMdCtx = EVP_MD_CTX_create();
    140     if (!pEvpMdCtx)
    141         return RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_MD_CTX_create failed");
    142     int rcOssl;
    143     if (EVP_VerifyInit_ex(pEvpMdCtx, pEvpMdType, NULL /*engine*/))
    144     {
    145         /* Create an EVP public key. */
    146         EVP_PKEY *pEvpPublicKey = EVP_PKEY_new();
    147         if (pEvpPublicKey)
     115    /* Create an EVP public key. */
     116    EVP_PKEY     *pEvpPublicKey = NULL;
     117    const EVP_MD *pEvpMdType = NULL;
     118    int rcOssl = rtCrKeyToOpenSslKey(hPublicKey, true /*fNeedPublic*/, pAlgorithm->szObjId, &pEvpPublicKey, &pEvpMdType, pErrInfo);
     119    if (RT_SUCCESS(rcOssl))
     120    {
     121        EVP_MD_CTX *pEvpMdCtx = EVP_MD_CTX_create();
     122        if (pEvpMdCtx)
    148123        {
    149 # if OPENSSL_VERSION_NUMBER >= 0x10001000 && !defined(LIBRESSL_VERSION_NUMBER)
    150             if (EVP_PKEY_set_type(pEvpPublicKey, idAlgoPkey))
     124            if (EVP_VerifyInit_ex(pEvpMdCtx, pEvpMdType, NULL /*engine*/))
    151125            {
    152                 int idKeyType = EVP_PKEY_base_id(pEvpPublicKey);
    153 # else
    154                 int idKeyType = pEvpPublicKey->type = EVP_PKEY_type(pEvpMdType->required_pkey_type[0]);
    155 # endif
    156                 if (idKeyType != NID_undef)
    157                 {
    158                     const unsigned char *puchPublicKey = RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey);
    159                     if (d2i_PublicKey(idKeyType, &pEvpPublicKey, &puchPublicKey, RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey)))
    160                     {
    161                         /* Digest the data. */
    162                         EVP_VerifyUpdate(pEvpMdCtx, pvData, cbData);
    163 
    164                         /* Verify the signature. */
    165                         if (EVP_VerifyFinal(pEvpMdCtx,
    166                                             RTASN1BITSTRING_GET_BIT0_PTR(pSignatureValue),
    167                                             RTASN1BITSTRING_GET_BYTE_SIZE(pSignatureValue),
    168                                             pEvpPublicKey) > 0)
    169                             rcOssl = VINF_SUCCESS;
    170                         else
    171                             rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED, "EVP_VerifyFinal failed");
    172                     }
    173                     else
    174                         rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED, "d2i_PublicKey failed");
    175                 }
     126                /* Digest the data. */
     127                EVP_VerifyUpdate(pEvpMdCtx, pvData, cbData);
     128
     129                /* Verify the signature. */
     130                if (EVP_VerifyFinal(pEvpMdCtx,
     131                                    RTASN1BITSTRING_GET_BIT0_PTR(pSignatureValue),
     132                                    RTASN1BITSTRING_GET_BYTE_SIZE(pSignatureValue),
     133                                    pEvpPublicKey) > 0)
     134                    rcOssl = VINF_SUCCESS;
    176135                else
    177 # if OPENSSL_VERSION_NUMBER < 0x10001000 || defined(LIBRESSL_VERSION_NUMBER)
    178                     rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_type() failed");
    179 # else
    180                     rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_base_id() failed");
     136                    rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED, "EVP_VerifyFinal failed");
     137
     138                /* Cleanup and return: */
    181139            }
    182140            else
    183                 rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
    184                                        "EVP_PKEY_set_type(%u) failed (sig algo %s)", idAlgoPkey, pszAlgoSn);
    185 # endif
    186             /* Cleanup and return.*/
    187             EVP_PKEY_free(pEvpPublicKey);
     141                rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALOG_INIT_FAILED,
     142                                       "EVP_VerifyInit_ex failed (algorithm type is %s)", pAlgorithm->szObjId);
     143            EVP_MD_CTX_destroy(pEvpMdCtx);
    188144        }
    189145        else
    190             rcOssl = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", iAlgoNid);
    191     }
    192     else
    193         rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALOG_INIT_FAILED,
    194                                "EVP_VerifyInit_ex failed (algorithm type is %s / %s)", pszAlgoSn, pAlgorithm->szObjId);
    195     EVP_MD_CTX_destroy(pEvpMdCtx);
     146            rcOssl = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_MD_CTX_create failed");
     147        EVP_PKEY_free(pEvpPublicKey);
     148    }
    196149
    197150    /*
     
    211164
    212165
    213 RTDECL(int) RTCrPkixPubKeyVerifySignedDigest(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey,
     166RTDECL(int) RTCrPkixPubKeyVerifySignedDigest(PCRTASN1OBJID pAlgorithm, RTCRKEY hPublicKey, PCRTASN1DYNTYPE pParameters,
    214167                                             void const *pvSignedDigest, size_t cbSignedDigest, RTCRDIGEST hDigest,
    215168                                             PRTERRINFO pErrInfo)
     
    228181    }
    229182
    230     AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER);
    231     AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_POINTER);
     183    AssertPtrReturn(hPublicKey, VERR_INVALID_POINTER);
     184    Assert(RTCrKeyHasPublicPart(hPublicKey));
    232185
    233186    AssertPtrReturn(pvSignedDigest, VERR_INVALID_POINTER);
     
    247200     */
    248201    RTCRPKIXSIGNATURE hSignature;
    249     int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, false /*fSigning*/, pPublicKey, pParameters);
     202    int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, hPublicKey, pParameters, false /*fSigning*/);
    250203    if (RT_FAILURE(rcIprt))
    251204        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
     
    263216     * Validate using OpenSSL EVP.
    264217     */
    265     rtCrOpenSslInit();
    266 
     218    /* Combine encryption and digest if the algorithm doesn't specify the digest type. */
    267219    const char *pszAlgObjId = pAlgorithm->szObjId;
    268220    if (!strcmp(pszAlgObjId, RTCRX509ALGORITHMIDENTIFIERID_RSA))
     
    274226    }
    275227
    276     /* Translate the algorithm ID into a EVP message digest type pointer. */
    277     int iAlgoNid = OBJ_txt2nid(pszAlgObjId);
    278     if (iAlgoNid == NID_undef)
    279         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN,
    280                              "Unknown public key algorithm [OpenSSL]: %s", pszAlgObjId);
    281     const char *pszAlgoSn = OBJ_nid2sn(iAlgoNid);
    282 
    283 # if OPENSSL_VERSION_NUMBER >= 0x10001000 && !defined(LIBRESSL_VERSION_NUMBER)
    284     int idAlgoPkey = 0;
    285     int idAlgoMd = 0;
    286     if (!OBJ_find_sigid_algs(iAlgoNid, &idAlgoMd, &idAlgoPkey))
    287         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    288                              "OBJ_find_sigid_algs failed on %u (%s, %s)", iAlgoNid, pszAlgoSn, pAlgorithm->szObjId);
    289     const EVP_MD *pEvpMdType = EVP_get_digestbynid(idAlgoMd);
    290     if (!pEvpMdType)
    291         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    292                              "EVP_get_digestbynid failed on %d (%s, %s)", idAlgoMd, pszAlgoSn, pAlgorithm->szObjId);
    293 # else
    294     const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlgoSn);
    295     if (!pEvpMdType)
    296         return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
    297                              "EVP_get_digestbyname failed on %s (%s)", pszAlgoSn, pszAlgObjId);
    298 # endif
    299 
    300228    /* Create an EVP public key. */
    301     int rcOssl;
    302     EVP_PKEY *pEvpPublicKey = EVP_PKEY_new();
    303     if (pEvpPublicKey)
    304     {
    305 # if OPENSSL_VERSION_NUMBER >= 0x10001000 && !defined(LIBRESSL_VERSION_NUMBER)
    306         if (EVP_PKEY_set_type(pEvpPublicKey, idAlgoPkey))
     229    EVP_PKEY     *pEvpPublicKey = NULL;
     230    const EVP_MD *pEvpMdType = NULL;
     231    int rcOssl = rtCrKeyToOpenSslKey(hPublicKey, true /*fNeedPublic*/, pszAlgObjId, &pEvpPublicKey, &pEvpMdType, pErrInfo);
     232    if (RT_SUCCESS(rcOssl))
     233    {
     234        /* Create an EVP public key context we can use to validate the digest. */
     235        EVP_PKEY_CTX *pEvpPKeyCtx = EVP_PKEY_CTX_new(pEvpPublicKey, NULL);
     236        if (pEvpPKeyCtx)
    307237        {
    308             int idKeyType = EVP_PKEY_base_id(pEvpPublicKey);
    309 # else
    310             int idKeyType = pEvpPublicKey->type = EVP_PKEY_type(pEvpMdType->required_pkey_type[0]);
    311 # endif
    312             if (idKeyType != NID_undef)
    313 
     238            rcOssl = EVP_PKEY_verify_init(pEvpPKeyCtx);
     239            if (rcOssl > 0)
    314240            {
    315                 const unsigned char *puchPublicKey = RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey);
    316                 if (d2i_PublicKey(idKeyType, &pEvpPublicKey, &puchPublicKey, RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey)))
     241                rcOssl = EVP_PKEY_CTX_set_signature_md(pEvpPKeyCtx, pEvpMdType);
     242                if (rcOssl > 0)
    317243                {
    318                     /* Create an EVP public key context we can use to validate the digest. */
    319                     EVP_PKEY_CTX *pEvpPKeyCtx = EVP_PKEY_CTX_new(pEvpPublicKey, NULL);
    320                     if (pEvpPKeyCtx)
    321                     {
    322                         rcOssl = EVP_PKEY_verify_init(pEvpPKeyCtx);
    323                         if (rcOssl > 0)
    324                         {
    325                             rcOssl = EVP_PKEY_CTX_set_signature_md(pEvpPKeyCtx, pEvpMdType);
    326                             if (rcOssl > 0)
    327                             {
    328                                 /* Get the digest from hDigest and verify it. */
    329                                 rcOssl = EVP_PKEY_verify(pEvpPKeyCtx,
    330                                                          (uint8_t const *)pvSignedDigest,
    331                                                          cbSignedDigest,
    332                                                          RTCrDigestGetHash(hDigest),
    333                                                          RTCrDigestGetHashSize(hDigest));
    334                                 if (rcOssl > 0)
    335                                     rcOssl = VINF_SUCCESS;
    336                                 else
    337                                     rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED,
    338                                                            "EVP_PKEY_verify failed (%d)", rcOssl);
    339                             }
    340                             else
    341                                 rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
    342                                                        "EVP_PKEY_CTX_set_signature_md failed (%d)", rcOssl);
    343                         }
    344                         else
    345                             rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
    346                                                    "EVP_PKEY_verify_init failed (%d)", rcOssl);
    347                         EVP_PKEY_CTX_free(pEvpPKeyCtx);
    348                     }
     244                    /* Get the digest from hDigest and verify it. */
     245                    rcOssl = EVP_PKEY_verify(pEvpPKeyCtx,
     246                                             (uint8_t const *)pvSignedDigest,
     247                                             cbSignedDigest,
     248                                             RTCrDigestGetHash(hDigest),
     249                                             RTCrDigestGetHashSize(hDigest));
     250                    if (rcOssl > 0)
     251                        rcOssl = VINF_SUCCESS;
    349252                    else
    350                         rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_CTX_new failed");
     253                        rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED,
     254                                               "EVP_PKEY_verify failed (%d)", rcOssl);
     255                    /* Cleanup and return: */
    351256                }
    352257                else
    353                     rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED, "d2i_PublicKey failed");
     258                    rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     259                                           "EVP_PKEY_CTX_set_signature_md failed (%d)", rcOssl);
    354260            }
    355261            else
    356 # if OPENSSL_VERSION_NUMBER < 0x10001000 || defined(LIBRESSL_VERSION_NUMBER)
    357                 rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_type() failed");
    358 # else
    359                 rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_base_id() failed");
     262                rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     263                                       "EVP_PKEY_verify_init failed (%d)", rcOssl);
     264            EVP_PKEY_CTX_free(pEvpPKeyCtx);
    360265        }
    361266        else
    362             rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
    363                                    "EVP_PKEY_set_type(%u) failed (sig algo %s)", idAlgoPkey, pszAlgoSn);
    364 # endif
    365 
    366         /* Cleanup and return.*/
     267            rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_CTX_new failed");
    367268        EVP_PKEY_free(pEvpPublicKey);
    368269    }
    369     else
    370         rcOssl = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", iAlgoNid);
    371270
    372271    /*
     
    385284}
    386285
     286
     287RTDECL(int) RTCrPkixPubKeyVerifySignedDigestByCertPubKeyInfo(PCRTCRX509SUBJECTPUBLICKEYINFO pCertPubKeyInfo,
     288                                                             void const *pvSignedDigest, size_t cbSignedDigest,
     289                                                             RTCRDIGEST hDigest, PRTERRINFO pErrInfo)
     290{
     291    RTCRKEY hPublicKey;
     292    int rc = RTCrKeyCreateFromPublicAlgorithmAndBits(&hPublicKey, &pCertPubKeyInfo->Algorithm.Algorithm,
     293                                                     &pCertPubKeyInfo->SubjectPublicKey, pErrInfo, NULL);
     294    if (RT_SUCCESS(rc))
     295    {
     296        rc = RTCrPkixPubKeyVerifySignedDigest(&pCertPubKeyInfo->Algorithm.Algorithm, hPublicKey,
     297                                              &pCertPubKeyInfo->Algorithm.Parameters, pvSignedDigest, cbSignedDigest,
     298                                              hDigest, pErrInfo);
     299
     300        uint32_t cRefs = RTCrKeyRelease(hPublicKey);
     301        Assert(cRefs == 0); RT_NOREF(cRefs);
     302    }
     303    return rc;
     304}
     305
  • trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp

    r69111 r73665  
    3232#include <iprt/crypto/x509.h>
    3333#include <iprt/crypto/pkix.h>
     34#include <iprt/crypto/key.h>
    3435
    3536#include <iprt/err.h>
     
    7677
    7778    /*
     79     * Wrap up the public key.
     80     */
     81    RTCRKEY hPubKey;
     82    int rc = RTCrKeyCreateFromPublicAlgorithmAndBits(&hPubKey, pAlgorithm, pPublicKey, pErrInfo, NULL);
     83    if (RT_FAILURE(rc))
     84        return rc;
     85
     86    /*
    7887     * Here we should recode the to-be-signed part as DER, but we'll ASSUME
    7988     * that it's already in DER encoding and only does this if there the
     
    8291    if (   pThis->TbsCertificate.SeqCore.Asn1Core.uData.pu8
    8392        && pThis->TbsCertificate.SeqCore.Asn1Core.cb > 0)
    84         return RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, pParameters, pPublicKey, &pThis->SignatureValue,
    85                                              RTASN1CORE_GET_RAW_ASN1_PTR(&pThis->TbsCertificate.SeqCore.Asn1Core),
    86                                              RTASN1CORE_GET_RAW_ASN1_SIZE(&pThis->TbsCertificate.SeqCore.Asn1Core),
    87                                              pErrInfo);
     93        rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters, &pThis->SignatureValue,
     94                                           RTASN1CORE_GET_RAW_ASN1_PTR(&pThis->TbsCertificate.SeqCore.Asn1Core),
     95                                           RTASN1CORE_GET_RAW_ASN1_SIZE(&pThis->TbsCertificate.SeqCore.Asn1Core),
     96                                           pErrInfo);
     97    else
     98    {
     99        uint32_t cbEncoded;
     100        int rc = RTAsn1EncodePrepare((PRTASN1CORE)&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
     101        if (RT_SUCCESS(rc))
     102        {
     103            void *pvTbsBits = RTMemTmpAlloc(cbEncoded);
     104            if (pvTbsBits)
     105            {
     106                rc = RTAsn1EncodeToBuffer(&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
     107                                          pvTbsBits, cbEncoded, pErrInfo);
     108                if (RT_SUCCESS(rc))
     109                    rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters,
     110                                                       &pThis->SignatureValue, pvTbsBits, cbEncoded, pErrInfo);
     111                else
     112                    AssertRC(rc);
     113                RTMemTmpFree(pvTbsBits);
     114            }
     115            else
     116                rc = VERR_NO_TMP_MEMORY;
     117        }
     118    }
    88119
    89     uint32_t cbEncoded;
    90     int rc = RTAsn1EncodePrepare((PRTASN1CORE)&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
    91     if (RT_SUCCESS(rc))
    92     {
    93         void *pvTbsBits = RTMemTmpAlloc(cbEncoded);
    94         if (pvTbsBits)
    95         {
    96             rc = RTAsn1EncodeToBuffer(&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
    97                                       pvTbsBits, cbEncoded, pErrInfo);
    98             if (RT_SUCCESS(rc))
    99                 rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, pParameters, pPublicKey,
    100                                                    &pThis->SignatureValue, pvTbsBits, cbEncoded, pErrInfo);
    101             else
    102                 AssertRC(rc);
    103             RTMemTmpFree(pvTbsBits);
    104         }
    105         else
    106             rc = VERR_NO_TMP_MEMORY;
    107     }
     120    /* Free the public key. */
     121    uint32_t cRefs = RTCrKeyRelease(hPubKey);
     122    Assert(cRefs == 0); NOREF(cRefs);
     123
    108124    return rc;
    109125}
  • trunk/src/VBox/Runtime/common/math/bignum.cpp

    r69111 r73665  
    840840        {
    841841            Assert(pBigNum->cAllocated > 0);
    842             if (pBigNum->fSensitive)
     842            if (!pBigNum->fSensitive)
     843                RTMemFree(pBigNum->pauElements);
     844            else
    843845            {
    844846                RTMemSaferFree(pBigNum->pauElements, pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE);
    845847                RT_ZERO(*pBigNum);
    846848            }
    847             RTMemFree(pBigNum->pauElements);
    848849            pBigNum->pauElements = NULL;
    849850        }
  • trunk/src/VBox/Runtime/include/internal/iprt-openssl.h

    r69111 r73665  
    3232
    3333RT_C_DECLS_BEGIN
     34struct evp_md_st;
     35struct evp_pkey_st;
    3436
    3537DECLHIDDEN(void) rtCrOpenSslInit(void);
     
    3739DECLHIDDEN(int)  rtCrOpenSslAddX509CertToStack(void *pvOsslStack, PCRTCRX509CERTIFICATE pCert);
    3840
     41DECLHIDDEN(int)  rtCrKeyToOpenSslKey(RTCRKEY hKey, bool fNeedPublic, const char *pszAlgoObjId,
     42                                     struct evp_pkey_st **ppEvpKey, const struct evp_md_st **ppEvpMdType, PRTERRINFO pErrInfo);
     43
    3944RT_C_DECLS_END
    4045
  • trunk/src/VBox/Runtime/include/internal/magics.h

    r73412 r73665  
    3535/** Magic number for RTAIOMGRINTFILE::u32Magic. (Ephraim Kishon) */
    3636#define RTAIOMGRFILE_MAGIC              UINT32_C(0x19240823)
     37/** Magic value for RTCRKEYINT::u32Magic. (Ronald Linn Rivest) */
     38#define RTCRKEYINT_MAGIC                UINT32_C(0x19470506)
    3739/** Magic number for RTDBGMODINT::u32Magic. (Charles Lloyd) */
    3840#define RTDBGAS_MAGIC                   UINT32_C(0x19380315)
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r72959 r73665  
    5353        tstRTCritSect \
    5454        tstRTCritSectRw \
     55        tstRTCrPkix-1 \
    5556        tstRTCrX509-1 \
    5657        tstRTCType \
     
    265266tstRTCritSectW32_DEFS = TRY_WIN32_CRIT
    266267
     268tstRTCrPkix-1_TEMPLATE      = VBOXR3TSTEXE
     269tstRTCrPkix-1_SOURCES       = tstRTCrPkix-1.cpp
     270
    267271tstRTCrX509-1_TEMPLATE      = VBOXR3TSTEXE
    268272tstRTCrX509-1_SOURCES       = tstRTCrX509-1.cpp
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