Changeset 73665 in vbox for trunk/src/VBox/Runtime/common/crypto/pkix-signature-rsa.cpp
- Timestamp:
- Aug 14, 2018 5:49:23 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/crypto/pkix-signature-rsa.cpp
r69111 r73665 41 41 #include "rsa-internal.h" 42 42 #include "pkix-signature-builtin.h" 43 #include "key-internal.h" 43 44 44 45 … … 53 54 /** Set if we're signing, clear if verifying. */ 54 55 bool fSigning; 55 /** The modulus. */56 RTBIGNUM Modulus;57 /** The exponent. */58 RTBIGNUM Exponent;59 56 60 57 /** Temporary big number for use when signing or verifiying. */ … … 138 135 /** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnInit} */ 139 136 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Init(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, void *pvOpaque, 140 bool fSigning, PCRTASN1BITSTRING pKey, PCRTASN1DYNTYPE pParams)137 bool fSigning, RTCRKEY hKey, PCRTASN1DYNTYPE pParams) 141 138 { 142 139 RT_NOREF_PV(pDesc); RT_NOREF_PV(pvState); RT_NOREF_PV(pvOpaque); … … 145 142 return VERR_CR_PKIX_SIGNATURE_TAKES_NO_PARAMETERS; 146 143 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 147 150 PRTCRPKIXSIGNATURERSA pThis = (PRTCRPKIXSIGNATURERSA)pvState; 148 151 pThis->fSigning = fSigning; 149 152 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; 196 154 } 197 155 … … 213 171 RT_NOREF_PV(fSigning); RT_NOREF_PV(pDesc); 214 172 Assert(pThis->fSigning == fSigning); 215 216 RTBigNumDestroy(&pThis->Modulus);217 RTBigNumDestroy(&pThis->Exponent);218 173 } 219 174 … … 246 201 * Figure out which hash and select the associate prebaked DigestInfo. 247 202 */ 248 RTDIGESTTYPE const enmDigest 203 RTDIGESTTYPE const enmDigest = RTCrDigestGetType(hDigest); 249 204 AssertReturn(enmDigest != RTDIGESTTYPE_INVALID && enmDigest != RTDIGESTTYPE_UNKNOWN, VERR_CR_PKIX_UNKNOWN_DIGEST_TYPE); 250 205 uint8_t const *pbDigestInfoStart = NULL; … … 297 252 298 253 /** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnVerify} */ 299 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Verify(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, 254 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Verify(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, RTCRKEY hKey, 300 255 RTCRDIGEST hDigest, void const *pvSignature, size_t cbSignature) 301 256 { … … 307 262 308 263 /* 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)) 312 274 return VERR_CR_PKIX_INVALID_SIGNATURE_LENGTH; 313 275 … … 321 283 return rc; 322 284 /* 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) 324 286 { 325 287 if (RTBigNumCompareWithU64(&pThis->TmpBigNum1, 0) >= 0) … … 329 291 if (RT_SUCCESS(rc)) 330 292 { 331 rc = RTBigNumModExp(&pThis->TmpBigNum2, &pThis->TmpBigNum1, &pThis->Exponent, &pThis->Modulus);293 rc = RTBigNumModExp(&pThis->TmpBigNum2, &pThis->TmpBigNum1, pExponent, pModulus); 332 294 if (RT_SUCCESS(rc)) 333 295 { … … 387 349 388 350 /** @impl_interface_method{RTCRPKIXSIGNATUREDESC,pfnSign} */ 389 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Sign(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, 351 static DECLCALLBACK(int) rtCrPkixSignatureRsa_Sign(PCRTCRPKIXSIGNATUREDESC pDesc, void *pvState, RTCRKEY hKey, 390 352 RTCRDIGEST hDigest, void *pvSignature, size_t *pcbSignature) 391 353 { 392 354 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; 396 413 } 397 414
Note:
See TracChangeset
for help on using the changeset viewer.