VirtualBox

Changeset 59689 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Feb 15, 2016 9:25:36 PM (9 years ago)
Author:
vboxsync
Message:

IPRT: Added RTCrDigestGetAlgorithmOid, RTCrDigestTypeToAlgorithmOid, RTCrPkixPubKeyVerifySignedDigest, RTCrX509AlgorithmIdentifier_CombineEncryptionAndDigest, RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid, and RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid.

Location:
trunk/src/VBox/Runtime/common/crypto
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/crypto/digest-core.cpp

    r57358 r59689  
    3636#include <iprt/mem.h>
    3737#include <iprt/string.h>
     38#include <iprt/crypto/x509.h>
    3839
    3940
     
    337338}
    338339
     340
     341RTDECL(const char *) RTCrDigestGetAlgorithmOid(RTCRDIGEST hDigest)
     342{
     343    return RTCrDigestTypeToAlgorithmOid(RTCrDigestGetType(hDigest));
     344}
     345
     346
     347RTDECL(const char *) RTCrDigestTypeToAlgorithmOid(RTDIGESTTYPE enmDigestType)
     348{
     349    switch (enmDigestType)
     350    {
     351        case RTDIGESTTYPE_MD2:          return RTCRX509ALGORITHMIDENTIFIERID_MD2;
     352        case RTDIGESTTYPE_MD4:          return RTCRX509ALGORITHMIDENTIFIERID_MD4;
     353        case RTDIGESTTYPE_MD5:          return RTCRX509ALGORITHMIDENTIFIERID_MD5;
     354        case RTDIGESTTYPE_SHA1:         return RTCRX509ALGORITHMIDENTIFIERID_SHA1;
     355        case RTDIGESTTYPE_SHA224:       return RTCRX509ALGORITHMIDENTIFIERID_SHA224;
     356        case RTDIGESTTYPE_SHA256:       return RTCRX509ALGORITHMIDENTIFIERID_SHA256;
     357        case RTDIGESTTYPE_SHA384:       return RTCRX509ALGORITHMIDENTIFIERID_SHA384;
     358        case RTDIGESTTYPE_SHA512:       return RTCRX509ALGORITHMIDENTIFIERID_SHA512;
     359        default:                        return NULL;
     360    }
     361}
     362
  • trunk/src/VBox/Runtime/common/crypto/pkix-verify.cpp

    r57358 r59689  
    179179}
    180180
     181
     182RTDECL(int) RTCrPkixPubKeyVerifySignedDigest(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey,
     183                                             void const *pvSignedDigest, size_t cbSignedDigest, RTCRDIGEST hDigest,
     184                                             PRTERRINFO pErrInfo)
     185{
     186    /*
     187     * Valid input.
     188     */
     189    AssertPtrReturn(pAlgorithm, VERR_INVALID_POINTER);
     190    AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_POINTER);
     191
     192    if (pParameters)
     193    {
     194        AssertPtrReturn(pParameters, VERR_INVALID_POINTER);
     195        if (pParameters->enmType == RTASN1TYPE_NULL)
     196            pParameters = NULL;
     197    }
     198
     199    AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER);
     200    AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_POINTER);
     201
     202    AssertPtrReturn(pvSignedDigest, VERR_INVALID_POINTER);
     203    AssertReturn(cbSignedDigest, VERR_INVALID_PARAMETER);
     204
     205    AssertPtrReturn(hDigest, VERR_INVALID_HANDLE);
     206
     207    /*
     208     * Parameters are not currently supported (openssl code path).
     209     */
     210    if (pParameters)
     211        return RTErrInfoSet(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL,
     212                            "Cipher algorithm parameters are not yet supported.");
     213
     214    /*
     215     * Validate using IPRT.
     216     */
     217    RTCRPKIXSIGNATURE hSignature;
     218    int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, false /*fSigning*/, pPublicKey, pParameters);
     219    if (RT_FAILURE(rcIprt))
     220        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN,
     221                             "Unknown public key algorithm [IPRT]: %s", pAlgorithm->szObjId);
     222
     223    rcIprt = RTCrPkixSignatureVerify(hSignature, hDigest, pvSignedDigest, cbSignedDigest);
     224    if (RT_FAILURE(rcIprt))
     225        RTErrInfoSet(pErrInfo, rcIprt, "RTCrPkixSignatureVerifyBitString failed");
     226
     227    RTCrPkixSignatureRelease(hSignature);
     228
     229#ifdef IPRT_WITH_OPENSSL
     230    /*
     231     * Validate using OpenSSL EVP.
     232     */
     233    rtCrOpenSslInit();
     234
     235    const char *pszAlgObjId = pAlgorithm->szObjId;
     236    if (!strcmp(pszAlgObjId, RTCRX509ALGORITHMIDENTIFIERID_RSA))
     237    {
     238        pszAlgObjId = RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pszAlgObjId,
     239                                                                                   RTCrDigestGetAlgorithmOid(hDigest));
     240        AssertMsgStmt(pszAlgObjId, ("enc=%s hash=%s\n", pAlgorithm->szObjId, RTCrDigestGetAlgorithmOid(hDigest)),
     241                      pszAlgObjId = RTCrDigestGetAlgorithmOid(hDigest));
     242    }
     243
     244    /* Translate the algorithm ID into a EVP message digest type pointer. */
     245    int iAlgoNid = OBJ_txt2nid(pszAlgObjId);
     246    if (iAlgoNid == NID_undef)
     247        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN,
     248                             "Unknown public key algorithm [OpenSSL]: %s", pszAlgObjId);
     249    const char *pszAlogSn = OBJ_nid2sn(iAlgoNid);
     250    const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlogSn);
     251    if (!pEvpMdType)
     252        return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP,
     253                             "EVP_get_digestbyname failed on %s (%s)", pszAlogSn, pszAlgObjId);
     254
     255    /* Create an EVP public key. */
     256    int rcOssl;
     257    EVP_PKEY *pEvpPublicKey = EVP_PKEY_new();
     258    if (pEvpPublicKey)
     259    {
     260        pEvpPublicKey->type = EVP_PKEY_type(pEvpMdType->required_pkey_type[0]);
     261        if (pEvpPublicKey->type != NID_undef)
     262        {
     263            const unsigned char *puchPublicKey = RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey);
     264            if (d2i_PublicKey(pEvpPublicKey->type, &pEvpPublicKey, &puchPublicKey, RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey)))
     265            {
     266                /* Create an EVP public key context we can use to validate the digest. */
     267                EVP_PKEY_CTX *pEvpPKeyCtx = EVP_PKEY_CTX_new(pEvpPublicKey, NULL);
     268                if (pEvpPKeyCtx)
     269                {
     270                    rcOssl = EVP_PKEY_verify_init(pEvpPKeyCtx);
     271                    if (rcOssl > 0)
     272                    {
     273                        rcOssl = EVP_PKEY_CTX_set_signature_md(pEvpPKeyCtx, pEvpMdType);
     274                        if (rcOssl > 0)
     275                        {
     276                            /* Get the digest from hDigest and verify it. */
     277                            rcOssl = EVP_PKEY_verify(pEvpPKeyCtx,
     278                                                     (uint8_t const *)pvSignedDigest,
     279                                                     cbSignedDigest,
     280                                                     RTCrDigestGetHash(hDigest),
     281                                                     RTCrDigestGetHashSize(hDigest));
     282                            if (rcOssl > 0)
     283                                rcOssl = VINF_SUCCESS;
     284                            else
     285                                rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED,
     286                                                       "EVP_PKEY_verify failed (%d)", rcOssl);
     287                        }
     288                        else
     289                            rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     290                                                   "EVP_PKEY_CTX_set_signature_md failed (%d)", rcOssl);
     291                    }
     292                    else
     293                        rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     294                                               "EVP_PKEY_verify_init failed (%d)", rcOssl);
     295                    EVP_PKEY_CTX_free(pEvpPKeyCtx);
     296                }
     297                else
     298                    rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_CTX_new failed");
     299            }
     300            else
     301                rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED, "d2i_PublicKey failed");
     302        }
     303        else
     304            rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR,
     305                                   "EVP_PKEY_type(%d) failed", pEvpMdType->required_pkey_type[0]);
     306        /* Cleanup and return.*/
     307        EVP_PKEY_free(pEvpPublicKey);
     308    }
     309    else
     310        rcOssl = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", pEvpMdType->required_pkey_type[0]);
     311
     312    /*
     313     * Check the result.
     314     */
     315    if (RT_SUCCESS(rcIprt) && RT_SUCCESS(rcOssl))
     316        return VINF_SUCCESS;
     317    if (RT_FAILURE_NP(rcIprt) && RT_FAILURE_NP(rcOssl))
     318        return rcIprt;
     319    AssertMsgFailed(("rcIprt=%Rrc rcOssl=%Rrc\n", rcIprt, rcOssl));
     320    if (RT_FAILURE_NP(rcOssl))
     321        return rcOssl;
     322#endif /* IPRT_WITH_OPENSSL */
     323
     324    return rcIprt;
     325}
     326
  • trunk/src/VBox/Runtime/common/crypto/x509-core.cpp

    r57574 r59689  
    127127
    128128
    129 RTDECL(int) RTCrX509AlgorithmIdentifier_CompareDigestAndEncryptedDigest(PCRTCRX509ALGORITHMIDENTIFIER pDigest,
    130                                                                         PCRTCRX509ALGORITHMIDENTIFIER pEncryptedDigest)
     129RTDECL(int) RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid(const char *pszDigestOid,
     130                                                                              const char *pszEncryptedDigestOid)
    131131{
    132132    /* common */
    133     if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5))
    134     {
    135         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA))
     133    if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5))
     134    {
     135        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA))
    136136            return 0;
    137137    }
    138     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1))
    139     {
    140         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA))
     138    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1))
     139    {
     140        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA))
    141141            return 0;
    142142    }
    143     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256))
    144     {
    145         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA))
     143    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256))
     144    {
     145        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA))
    146146            return 0;
    147147    }
    148     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512))
    149     {
    150         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA))
     148    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512))
     149    {
     150        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA))
    151151            return 0;
    152152    }
    153153    /* Less common. */
    154     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD2))
    155     {
    156         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA))
     154    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2))
     155    {
     156        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA))
    157157            return 0;
    158158    }
    159     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD4))
    160     {
    161         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA))
     159    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4))
     160    {
     161        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA))
    162162            return 0;
    163163    }
    164     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384))
    165     {
    166         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA))
     164    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384))
     165    {
     166        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA))
    167167            return 0;
    168168    }
    169     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224))
    170     {
    171         if (!strcmp(pEncryptedDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA))
     169    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224))
     170    {
     171        if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA))
    172172            return 0;
    173173    }
    174     else if (!strcmp(pDigest->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
     174    else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
    175175    {
    176176        /* ?? */
     
    179179        return -1;
    180180    return 1;
     181}
     182
     183RTDECL(int) RTCrX509AlgorithmIdentifier_CompareDigestAndEncryptedDigest(PCRTCRX509ALGORITHMIDENTIFIER pDigest,
     184                                                                        PCRTCRX509ALGORITHMIDENTIFIER pEncryptedDigest)
     185{
     186    return RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid(pDigest->Algorithm.szObjId,
     187                                                                             pEncryptedDigest->Algorithm.szObjId);
     188}
     189
     190
     191RTDECL(const char *) RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(const char *pszEncryptionOid,
     192                                                                                  const char *pszDigestOid)
     193{
     194    /* RSA: */
     195    if (!strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_RSA))
     196    {
     197        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5)
     198            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA))
     199            return RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA;
     200        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1)
     201            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA))
     202            return RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA;
     203        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256)
     204            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA))
     205            return RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA;
     206        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512)
     207            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA))
     208            return RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA;
     209        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2)
     210            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA))
     211            return RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA;
     212        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4)
     213            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA))
     214            return RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA;
     215        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384)
     216            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA))
     217            return RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA;
     218        if (   !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224)
     219            || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA))
     220            return RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA;
     221
     222        /* if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL))
     223            return ???; */
     224    }
     225    else if (RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid(pszDigestOid, pszEncryptionOid) == 0)
     226        return pszEncryptionOid;
     227
     228    AssertMsgFailed(("enc=%s hash=%s\n", pszEncryptionOid, pszDigestOid));
     229    return NULL;
     230}
     231
     232
     233RTDECL(const char *) RTCrX509AlgorithmIdentifier_CombineEncryptionAndDigest(PCRTCRX509ALGORITHMIDENTIFIER pEncryption,
     234                                                                            PCRTCRX509ALGORITHMIDENTIFIER pDigest)
     235{
     236    return RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pEncryption->Algorithm.szObjId,
     237                                                                        pDigest->Algorithm.szObjId);
    181238}
    182239
Note: See TracChangeset for help on using the changeset viewer.

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