1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. 7 */ 8 9 #pragma ident "%Z%%M% %I% %E% SMI" 10 11 #include <kmfapiP.h> 12 #include <sha1.h> 13 #include <security/cryptoki.h> 14 15 #include <algorithm.h> 16 #include <ber_der.h> 17 18 #define MAX_PUBLIC_KEY_TEMPLATES (20) 19 #define MAX_PRIVATE_KEY_TEMPLATES (24) 20 #define MAX_SECRET_KEY_TEMPLATES (24) 21 22 static KMF_RETURN 23 create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, 24 CK_FLAGS wanted_flags) 25 { 26 CK_RV rv; 27 KMF_RETURN ret; 28 KMF_RETURN kmf_rv = KMF_OK; 29 CK_SLOT_ID_PTR pSlotList; 30 CK_ULONG pulCount; 31 CK_MECHANISM_INFO info; 32 int i; 33 34 ret = init_pk11(); 35 36 if (ret != KMF_OK) 37 return (ret); 38 39 rv = C_GetSlotList(0, NULL, &pulCount); 40 if (rv != CKR_OK) { 41 kmf_rv = KMF_ERR_UNINITIALIZED; 42 goto out; 43 } 44 45 pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID)); 46 if (pSlotList == NULL) { 47 kmf_rv = KMF_ERR_MEMORY; 48 goto out; 49 } 50 51 rv = C_GetSlotList(0, pSlotList, &pulCount); 52 if (rv != CKR_OK) { 53 kmf_rv = KMF_ERR_UNINITIALIZED; 54 goto out; 55 } 56 57 for (i = 0; i < pulCount; i++) { 58 rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info); 59 if (rv == CKR_OK && (info.flags & wanted_flags)) 60 break; 61 } 62 if (i < pulCount) { 63 rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, 64 NULL, NULL, sessionp); 65 66 if (rv != CKR_OK) { 67 kmf_rv = KMF_ERR_UNINITIALIZED; 68 } 69 } else { 70 kmf_rv = KMF_ERR_UNINITIALIZED; 71 } 72 73 out: 74 if (pSlotList != NULL) 75 free(pSlotList); 76 return (kmf_rv); 77 78 } 79 80 /* 81 * Name: PKCS_AddTemplate 82 * 83 * Description: 84 * Adds a CK_ATTRIBUTE value to an existing array of CK_ATTRIBUTES. Will 85 * not expand the array beyond the maximum specified size. 86 * 87 * Returns: 88 * TRUE - Attribute value succesfully added. 89 * FALSE - Maximum array size would be exceded. 90 */ 91 static int 92 PKCS_AddTemplate(CK_ATTRIBUTE *pTemplate, 93 CK_ULONG *ckNumTemplates, 94 CK_ULONG ckMaxTemplates, 95 CK_ATTRIBUTE_TYPE ckAttribCode, 96 CK_BYTE * pckBuffer, 97 CK_ULONG ckBufferLen) 98 { 99 if (*ckNumTemplates >= ckMaxTemplates) { 100 return (FALSE); 101 } 102 103 pTemplate[*ckNumTemplates].type = ckAttribCode; 104 pTemplate[*ckNumTemplates].pValue = pckBuffer; 105 pTemplate[*ckNumTemplates].ulValueLen = ckBufferLen; 106 (*ckNumTemplates)++; 107 108 return (TRUE); 109 } 110 111 /* 112 * Convert an SPKI data record to PKCS#11 113 * public key object. 114 */ 115 static KMF_RETURN 116 PKCS_CreatePublicKey( 117 const KMF_X509_SPKI *pKey, 118 CK_SESSION_HANDLE ckSession, 119 CK_OBJECT_HANDLE *pckPublicKey) 120 { 121 KMF_RETURN mrReturn = KMF_OK; 122 CK_RV ckRv; 123 124 CK_ATTRIBUTE ckTemplate[MAX_PUBLIC_KEY_TEMPLATES]; 125 CK_ULONG ckNumTemplates = 0; 126 127 /* Common object attributes */ 128 CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY; 129 CK_BBOOL ckToken = 0; 130 CK_BBOOL ckPrivate = 0; 131 132 /* Common key attributes */ 133 CK_KEY_TYPE ckKeyType; 134 CK_BBOOL ckDerive = CK_FALSE; 135 136 /* Common public key attributes */ 137 CK_BBOOL ckEncrypt = 1; 138 CK_BBOOL ckVerify = 1; 139 140 CK_BBOOL ckVerifyRecover = CK_FALSE; 141 CK_BBOOL ckWrap = CK_FALSE; 142 143 /* Key part array */ 144 KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS]; 145 uint32_t i, uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS; 146 KMF_ALGORITHM_INDEX AlgorithmId; 147 148 /* Parse the keyblob */ 149 (void) memset(KeyParts, 0, sizeof (KeyParts)); 150 151 AlgorithmId = X509_AlgorithmOidToAlgId((KMF_OID *) 152 &pKey->algorithm.algorithm); 153 154 mrReturn = ExtractSPKIData(pKey, AlgorithmId, KeyParts, &uNumKeyParts); 155 156 if (mrReturn != KMF_OK) 157 return (mrReturn); 158 159 /* Fill in the common object attributes */ 160 if (!PKCS_AddTemplate(ckTemplate, 161 &ckNumTemplates, 162 MAX_PUBLIC_KEY_TEMPLATES, 163 CKA_CLASS, 164 (CK_BYTE *)&ckObjClass, 165 sizeof (ckObjClass)) || 166 !PKCS_AddTemplate(ckTemplate, 167 &ckNumTemplates, 168 MAX_PUBLIC_KEY_TEMPLATES, 169 CKA_TOKEN, 170 (CK_BYTE *)&ckToken, 171 sizeof (ckToken)) || 172 !PKCS_AddTemplate(ckTemplate, 173 &ckNumTemplates, 174 MAX_PUBLIC_KEY_TEMPLATES, 175 CKA_PRIVATE, 176 (CK_BYTE *)&ckPrivate, 177 sizeof (ckPrivate))) { 178 mrReturn = KMF_ERR_INTERNAL; 179 goto cleanup; 180 } 181 182 /* Fill in the common key attributes */ 183 if (!PKCS_ConvertAlgorithmId2PKCSKeyType(AlgorithmId, 184 &ckKeyType)) { 185 goto cleanup; 186 } 187 if (!PKCS_AddTemplate(ckTemplate, 188 &ckNumTemplates, 189 MAX_PUBLIC_KEY_TEMPLATES, 190 CKA_KEY_TYPE, 191 (CK_BYTE *)&ckKeyType, 192 sizeof (ckKeyType)) || 193 !PKCS_AddTemplate(ckTemplate, 194 &ckNumTemplates, 195 MAX_PUBLIC_KEY_TEMPLATES, 196 CKA_DERIVE, 197 (CK_BYTE *)&ckDerive, 198 sizeof (ckDerive))) { 199 mrReturn = KMF_ERR_INTERNAL; 200 goto cleanup; 201 } 202 203 /* Add common public key attributes */ 204 if (!PKCS_AddTemplate(ckTemplate, 205 &ckNumTemplates, 206 MAX_PUBLIC_KEY_TEMPLATES, 207 CKA_ENCRYPT, 208 (CK_BYTE *)&ckEncrypt, 209 sizeof (ckEncrypt)) || 210 !PKCS_AddTemplate(ckTemplate, 211 &ckNumTemplates, 212 MAX_PUBLIC_KEY_TEMPLATES, 213 CKA_VERIFY, 214 (CK_BYTE *)&ckVerify, 215 sizeof (ckVerify)) || 216 !PKCS_AddTemplate(ckTemplate, 217 &ckNumTemplates, 218 MAX_PUBLIC_KEY_TEMPLATES, 219 CKA_VERIFY_RECOVER, 220 (CK_BYTE *)&ckVerifyRecover, 221 sizeof (ckVerifyRecover)) || 222 !PKCS_AddTemplate(ckTemplate, 223 &ckNumTemplates, 224 MAX_PUBLIC_KEY_TEMPLATES, 225 CKA_WRAP, 226 (CK_BYTE *)&ckWrap, 227 sizeof (ckWrap))) { 228 mrReturn = KMF_ERR_INTERNAL; 229 goto cleanup; 230 } 231 232 /* Add algorithm specific attributes */ 233 switch (ckKeyType) { 234 case CKK_RSA: 235 if (!PKCS_AddTemplate(ckTemplate, 236 &ckNumTemplates, 237 MAX_PUBLIC_KEY_TEMPLATES, 238 CKA_MODULUS, 239 (CK_BYTE *)KeyParts[KMF_RSA_MODULUS].Data, 240 (CK_ULONG)KeyParts[KMF_RSA_MODULUS].Length) || 241 !PKCS_AddTemplate(ckTemplate, 242 &ckNumTemplates, 243 MAX_PUBLIC_KEY_TEMPLATES, 244 CKA_PUBLIC_EXPONENT, 245 (CK_BYTE *)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Data, 246 (CK_ULONG)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Length)) { 247 mrReturn = KMF_ERR_INTERNAL; 248 goto cleanup; 249 } 250 break; 251 case CKK_DSA: 252 if (!PKCS_AddTemplate(ckTemplate, 253 &ckNumTemplates, 254 MAX_PUBLIC_KEY_TEMPLATES, 255 CKA_PRIME, 256 (CK_BYTE *)KeyParts[KMF_DSA_PRIME].Data, 257 (CK_ULONG)KeyParts[KMF_DSA_PRIME].Length) || 258 !PKCS_AddTemplate(ckTemplate, 259 &ckNumTemplates, 260 MAX_PUBLIC_KEY_TEMPLATES, 261 CKA_SUBPRIME, 262 (CK_BYTE *)KeyParts[KMF_DSA_SUB_PRIME].Data, 263 (CK_ULONG)KeyParts[KMF_DSA_SUB_PRIME].Length) || 264 !PKCS_AddTemplate(ckTemplate, 265 &ckNumTemplates, 266 MAX_PUBLIC_KEY_TEMPLATES, 267 CKA_BASE, 268 (CK_BYTE *)KeyParts[KMF_DSA_BASE].Data, 269 (CK_ULONG)KeyParts[KMF_DSA_BASE].Length) || 270 !PKCS_AddTemplate(ckTemplate, 271 &ckNumTemplates, 272 MAX_PUBLIC_KEY_TEMPLATES, 273 CKA_VALUE, 274 (CK_BYTE *)KeyParts[KMF_DSA_PUBLIC_VALUE].Data, 275 (CK_ULONG)KeyParts[KMF_DSA_PUBLIC_VALUE].Length)) { 276 mrReturn = KMF_ERR_INTERNAL; 277 goto cleanup; 278 } 279 break; 280 default: 281 mrReturn = KMF_ERR_BAD_PARAMETER; 282 } 283 284 if (mrReturn == KMF_OK) { 285 /* Instantiate the object */ 286 ckRv = C_CreateObject(ckSession, 287 ckTemplate, 288 ckNumTemplates, 289 pckPublicKey); 290 if (ckRv != CKR_OK) 291 mrReturn = KMF_ERR_INTERNAL; 292 } 293 294 cleanup: 295 for (i = 0; i < uNumKeyParts; i++) { 296 KMF_FreeData(&KeyParts[i]); 297 } 298 299 return (mrReturn); 300 } 301 302 /* 303 * PKCS_AcquirePublicKeyHandle 304 * 305 * Given an assymetric key keyblob, attempts to find the appropriate 306 * public key. 307 * 308 * Methods of finding the public key: 309 * - Public Key with data present: 310 * Parses the key and creates a temporary session object. 311 * - Public Key with handle: 312 * The handle is type converted and returned. Validity of the handle is 313 * not checked. 314 * - Public Key with label: 315 * Attempts to find a public key with the corresponding label. 316 */ 317 KMF_RETURN 318 PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, 319 const KMF_X509_SPKI *pKey, 320 CK_KEY_TYPE ckRequestedKeyType, 321 CK_OBJECT_HANDLE *pckKeyHandle, 322 KMF_BOOL *pbTemporary) 323 { 324 KMF_RETURN mrReturn = KMF_OK; 325 326 327 /* Key searching variables */ 328 CK_OBJECT_HANDLE ckKeyHandle; 329 CK_OBJECT_CLASS ckObjClass; 330 CK_KEY_TYPE ckKeyType; 331 CK_ATTRIBUTE ckTemplate[3]; 332 CK_ULONG ckNumTemplates; 333 static const CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) / 334 sizeof (CK_ATTRIBUTE)); 335 CK_RV ckRv; 336 337 /* Extract the data from the SPKI into individual fields */ 338 mrReturn = PKCS_CreatePublicKey(pKey, ckSession, &ckKeyHandle); 339 if (mrReturn != KMF_OK) 340 return (mrReturn); 341 342 *pbTemporary = KMF_TRUE; 343 344 /* Fetch the key class and algorithm from the object */ 345 ckNumTemplates = 0; 346 if (!PKCS_AddTemplate(ckTemplate, 347 &ckNumTemplates, 348 ckMaxTemplates, 349 CKA_CLASS, 350 (CK_BYTE *)&ckObjClass, 351 sizeof (ckObjClass)) || 352 !PKCS_AddTemplate(ckTemplate, 353 &ckNumTemplates, 354 ckMaxTemplates, 355 CKA_KEY_TYPE, 356 (CK_BYTE *)&ckKeyType, 357 sizeof (ckKeyType))) { 358 return (KMF_ERR_INTERNAL); 359 } 360 ckRv = C_GetAttributeValue(ckSession, 361 ckKeyHandle, 362 ckTemplate, 363 ckNumTemplates); 364 if (ckRv != CKR_OK) { 365 return (ckRv); 366 } 367 368 /* Make sure the results match the expected values */ 369 if ((ckKeyType != ckRequestedKeyType) || 370 (ckObjClass != CKO_PUBLIC_KEY)) { 371 if (*pbTemporary == KMF_TRUE) { 372 (void) C_DestroyObject(ckSession, ckKeyHandle); 373 } 374 375 return (KMF_ERR_BAD_KEY_FORMAT); 376 } 377 378 /* Set the return values */ 379 *pckKeyHandle = ckKeyHandle; 380 381 return (KMF_OK); 382 } 383 384 KMF_SIGNATURE_MODE 385 PKCS_GetDefaultSignatureMode(KMF_ALGORITHM_INDEX AlgId) 386 { 387 KMF_SIGNATURE_MODE AlgMode; 388 389 switch (AlgId) { 390 case KMF_ALGID_RSA: 391 case KMF_ALGID_MD5WithRSA: 392 case KMF_ALGID_MD2WithRSA: 393 case KMF_ALGID_SHA1WithRSA: 394 AlgMode = KMF_ALGMODE_PKCS1_EMSA_V15; 395 break; 396 default: 397 AlgMode = KMF_ALGMODE_NONE; 398 break; 399 } 400 401 return (AlgMode); 402 } 403 404 KMF_RETURN 405 PKCS_VerifyData(KMF_HANDLE_T kmfh, 406 KMF_ALGORITHM_INDEX AlgorithmId, 407 KMF_X509_SPKI *keyp, 408 KMF_DATA *data, 409 KMF_DATA *signed_data) 410 { 411 KMF_RETURN rv = KMF_OK; 412 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 413 CK_RV ckRv; 414 CK_MECHANISM ckMechanism; 415 CK_OBJECT_HANDLE ckKeyHandle; 416 KMF_BOOL bTempKey; 417 CK_SESSION_HANDLE ckSession = 0; 418 419 if (AlgorithmId == KMF_ALGID_NONE) 420 return (KMF_ERR_BAD_ALGORITHM); 421 422 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 423 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 424 425 if (!pAlgMap) 426 return (KMF_ERR_BAD_ALGORITHM); 427 428 rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 429 CKF_VERIFY); 430 431 if (rv != KMF_OK) 432 return (rv); 433 434 /* Fetch the verifying key */ 435 rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 436 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 437 438 if (rv != KMF_OK) { 439 (void) C_CloseSession(ckSession); 440 return (rv); 441 } 442 443 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 444 ckMechanism.pParameter = NULL; 445 ckMechanism.ulParameterLen = 0; 446 447 ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); 448 if (ckRv != CKR_OK) { 449 if (bTempKey) 450 (void) C_DestroyObject(ckSession, ckKeyHandle); 451 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 452 kmfh->lasterr.errcode = ckRv; 453 (void) C_CloseSession(ckSession); 454 return (KMF_ERR_INTERNAL); 455 } 456 457 ckRv = C_Verify(ckSession, 458 (CK_BYTE *)data->Data, 459 (CK_ULONG)data->Length, 460 (CK_BYTE *)signed_data->Data, 461 (CK_ULONG)signed_data->Length); 462 463 if (ckRv != CKR_OK) { 464 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 465 kmfh->lasterr.errcode = ckRv; 466 rv = KMF_ERR_INTERNAL; 467 } 468 if (bTempKey) 469 (void) C_DestroyObject(ckSession, ckKeyHandle); 470 471 (void) C_CloseSession(ckSession); 472 return (rv); 473 474 } 475 476 KMF_RETURN 477 PKCS_EncryptData(KMF_HANDLE_T kmfh, 478 KMF_ALGORITHM_INDEX AlgorithmId, 479 KMF_X509_SPKI *keyp, 480 KMF_DATA *plaintext, 481 KMF_DATA *ciphertext) 482 { 483 KMF_RETURN rv = KMF_OK; 484 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 485 CK_RV ckRv; 486 CK_MECHANISM ckMechanism; 487 CK_OBJECT_HANDLE ckKeyHandle; 488 KMF_BOOL bTempKey; 489 CK_SESSION_HANDLE ckSession = NULL; 490 CK_ULONG out_len = 0, in_len = 0, total_encrypted = 0; 491 uint8_t *in_data, *out_data; 492 int i, blocks, block_size; 493 CK_ATTRIBUTE ckTemplate[2]; 494 CK_ULONG ckNumTemplates; 495 CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) / 496 sizeof (CK_ATTRIBUTE)); 497 498 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 499 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 500 501 if (!pAlgMap) 502 return (KMF_ERR_BAD_ALGORITHM); 503 504 rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 505 CKF_ENCRYPT); 506 507 if (rv != KMF_OK) 508 return (rv); 509 510 /* Get the public key used in encryption */ 511 rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 512 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 513 514 if (rv != KMF_OK) { 515 (void) C_CloseSession(ckSession); 516 return (rv); 517 } 518 519 /* Get the modulus length */ 520 ckNumTemplates = 0; 521 if (!PKCS_AddTemplate(ckTemplate, 522 &ckNumTemplates, 523 ckMaxTemplates, 524 CKA_MODULUS, 525 (CK_BYTE *)NULL, 526 sizeof (CK_ULONG))) { 527 if (bTempKey) 528 (void) C_DestroyObject(ckSession, ckKeyHandle); 529 (void) C_CloseSession(ckSession); 530 return (KMF_ERR_INTERNAL); 531 } 532 533 ckRv = C_GetAttributeValue(ckSession, 534 ckKeyHandle, 535 ckTemplate, 536 ckNumTemplates); 537 538 if (ckRv != CKR_OK) { 539 if (bTempKey) 540 (void) C_DestroyObject(ckSession, ckKeyHandle); 541 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 542 kmfh->lasterr.errcode = ckRv; 543 (void) C_CloseSession(ckSession); 544 return (KMF_ERR_INTERNAL); 545 } 546 out_len = ckTemplate[0].ulValueLen; 547 548 if (out_len > ciphertext->Length) { 549 if (bTempKey) 550 (void) C_DestroyObject(ckSession, ckKeyHandle); 551 (void) C_CloseSession(ckSession); 552 return (KMF_ERR_BUFFER_SIZE); 553 } 554 555 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 556 ckMechanism.pParameter = NULL_PTR; 557 ckMechanism.ulParameterLen = 0; 558 559 /* Compute the fixed input data length for single-part encryption */ 560 block_size = out_len - 11; 561 562 in_data = plaintext->Data; 563 out_data = ciphertext->Data; 564 565 blocks = plaintext->Length/block_size; 566 567 for (i = 0; i < blocks; i++) { 568 ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle); 569 if (ckRv != CKR_OK) { 570 if (bTempKey) 571 (void) C_DestroyObject(ckSession, ckKeyHandle); 572 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 573 kmfh->lasterr.errcode = ckRv; 574 (void) C_CloseSession(ckSession); 575 return (KMF_ERR_INTERNAL); 576 } 577 ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, block_size, 578 (CK_BYTE_PTR)out_data, &out_len); 579 580 if (ckRv != CKR_OK) { 581 if (bTempKey) 582 (void) C_DestroyObject(ckSession, ckKeyHandle); 583 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 584 kmfh->lasterr.errcode = ckRv; 585 (void) C_CloseSession(ckSession); 586 return (KMF_ERR_INTERNAL); 587 } 588 589 out_data += out_len; 590 total_encrypted += out_len; 591 in_data += block_size; 592 } 593 594 if (plaintext->Length % block_size) { 595 /* Encrypt the remaining data */ 596 ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle); 597 if (ckRv != CKR_OK) { 598 if (bTempKey) 599 (void) C_DestroyObject(ckSession, ckKeyHandle); 600 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 601 kmfh->lasterr.errcode = ckRv; 602 (void) C_CloseSession(ckSession); 603 return (KMF_ERR_INTERNAL); 604 } 605 606 in_len = plaintext->Length % block_size; 607 ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, in_len, 608 (CK_BYTE_PTR)out_data, &out_len); 609 610 if (ckRv != CKR_OK) { 611 if (bTempKey) 612 (void) C_DestroyObject(ckSession, ckKeyHandle); 613 kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 614 kmfh->lasterr.errcode = ckRv; 615 (void) C_CloseSession(ckSession); 616 return (KMF_ERR_INTERNAL); 617 } 618 619 out_data += out_len; 620 total_encrypted += out_len; 621 in_data += in_len; 622 } 623 624 ciphertext->Length = total_encrypted; 625 626 if (bTempKey) 627 (void) C_DestroyObject(ckSession, ckKeyHandle); 628 629 (void) C_CloseSession(ckSession); 630 return (rv); 631 632 } 633 634 static void 635 DigestData(KMF_DATA *IDInput, KMF_DATA *IDOutput) 636 { 637 SHA1_CTX ctx; 638 639 SHA1Init(&ctx); 640 SHA1Update(&ctx, IDInput->Data, IDInput->Length); 641 SHA1Final(IDOutput->Data, &ctx); 642 643 IDOutput->Length = SHA1_DIGEST_LENGTH; 644 } 645 646 KMF_RETURN 647 GetIDFromSPKI(KMF_X509_SPKI *spki, KMF_DATA *ID) 648 { 649 KMF_RETURN rv = KMF_OK; 650 KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS]; 651 uint32_t uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS; 652 KMF_ALGORITHM_INDEX algId; 653 int i; 654 655 if (ID == NULL || spki == NULL) 656 return (KMF_ERR_BAD_PARAMETER); 657 658 ID->Data = (uchar_t *)malloc(SHA1_HASH_LENGTH); 659 if (ID->Data == NULL) 660 return (KMF_ERR_MEMORY); 661 662 ID->Length = SHA1_HASH_LENGTH; 663 664 algId = X509_AlgorithmOidToAlgId(&spki->algorithm.algorithm); 665 666 rv = ExtractSPKIData(spki, algId, KeyParts, &uNumKeyParts); 667 if (rv != KMF_OK) 668 return (rv); 669 670 /* Check the KEY algorithm */ 671 if (algId == KMF_ALGID_RSA) { 672 DigestData(&KeyParts[KMF_RSA_MODULUS], ID); 673 } else if (algId == KMF_ALGID_DSA) { 674 DigestData(&KeyParts[KMF_DSA_PUBLIC_VALUE], ID); 675 } else { 676 /* We only support RSA and DSA keys for now */ 677 rv = KMF_ERR_BAD_ALGORITHM; 678 } 679 680 681 for (i = 0; i < uNumKeyParts; i++) { 682 if (KeyParts[i].Data != NULL) 683 free(KeyParts[i].Data); 684 } 685 686 if (rv != KMF_OK && ID->Data != NULL) { 687 free(ID->Data); 688 ID->Data = NULL; 689 ID->Length = 0; 690 } 691 692 return (rv); 693 } 694