VirtualBox

Ignore:
Timestamp:
Aug 14, 2018 5:49:23 PM (6 years ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
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