1/* 2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18#ifdef BSAFE_CSP_ENABLE 19 20 21/* 22 * bsafePKCS1.cpp - support for PKCS1 format RSA public key blobs, which for some 23 * reason, BSAFE doesn't know about. 24 */ 25 26#include "bsafePKCS1.h" 27#include "bsafecspi.h" 28#include "cspdebugging.h" 29#include "bsobjects.h" 30#include <Security/pkcs1oids.h> /* for RSAPublicKey */ 31#include <Security/cdsaUtils.h> 32#include <Security/cssmerrno.h> 33 34/* 35 * Simple conversion between BSAFE ITEM and snacc BigIntegerStr 36 */ 37static void BS_ItemToSnaccBigInt( 38 const ITEM &item, 39 BigIntegerStr &snaccInt) 40{ 41 snaccInt.Set(reinterpret_cast<const char *>(item.data), item.len); 42} 43 44/* 45 * This one doesn't do a malloc - the ITEM is only valid as long as 46 * snaccInt is! 47 */ 48static void BS_snaccBigIntToItem( 49 BigIntegerStr &snaccInt, // not const - we're passing a ptr 50 ITEM &item) 51{ 52 char *cp = snaccInt; 53 item.data = reinterpret_cast<unsigned char *>(cp); 54 item.len = snaccInt.Len(); 55} 56 57/* 58 * Given a PKCS1-formatted key blob, decode the blob into components and do 59 * a B_SetKeyInfo on the specified BSAFE key. 60 */ 61void BS_setKeyPkcs1( 62 const CssmData &pkcs1Blob, 63 B_KEY_OBJ bsKey) 64{ 65 /* DER-decode the blob */ 66 RSAPublicKey snaccPubKey; 67 68 try { 69 SC_decodeAsnObj(pkcs1Blob, snaccPubKey); 70 } 71 catch(const CssmError &cerror) { 72 CSSM_RETURN crtn = cerror.cssmError(); 73 74 errorLog1("BS_setKeyPkcs1: SC_decodeAsnObj returned %s\n", 75 cssmErrorString(crtn).c_str()); 76 switch(crtn) { 77 case CSSMERR_CSSM_MEMORY_ERROR: 78 crtn = CSSMERR_CSP_MEMORY_ERROR; 79 break; 80 case CSSMERR_CSSM_INVALID_INPUT_POINTER: 81 crtn = CSSMERR_CSP_INVALID_KEY; 82 default: 83 break; 84 } 85 CssmError::throwMe(crtn); 86 } 87 88 /* 89 * Convert BigIntegerStr modulus, publicExponent into 90 * ITEMS in an A_RSA_KEY. 91 */ 92 A_RSA_KEY rsaKey; 93 BS_snaccBigIntToItem(snaccPubKey.modulus, rsaKey.modulus); 94 BS_snaccBigIntToItem(snaccPubKey.publicExponent, rsaKey.exponent); 95 96 BSafe::check( 97 B_SetKeyInfo(bsKey, KI_RSAPublic, POINTER(&rsaKey)), true); 98} 99 100/* 101 * Obtain public key blob info, PKCS1 format. 102 */ 103void BS_GetKeyPkcs1( 104 const B_KEY_OBJ bsKey, 105 CssmOwnedData &pkcs1Blob) 106{ 107 /* get modulus/exponent info from BSAFE */ 108 A_RSA_KEY *rsaKey; 109 BSafe::check( 110 B_GetKeyInfo((POINTER *)&rsaKey, bsKey, KI_RSAPublic), true); 111 112 /* Cook up a snacc-style RSAPublic key */ 113 RSAPublicKey snaccPubKey; 114 BS_ItemToSnaccBigInt(rsaKey->modulus, snaccPubKey.modulus); 115 BS_ItemToSnaccBigInt(rsaKey->exponent, snaccPubKey.publicExponent); 116 117 /* estimate max size, BER-encode */ 118 size_t maxSize = 2 * (rsaKey->modulus.len + rsaKey->exponent.len); 119 try { 120 SC_encodeAsnObj(snaccPubKey, pkcs1Blob, maxSize); 121 } 122 catch(const CssmError &cerror) { 123 CSSM_RETURN crtn = cerror.cssmError(); 124 125 errorLog1("BS_GetKeyPkcs1: SC_encodeAsnObj returned %s\n", 126 cssmErrorString(crtn).c_str()); 127 switch(crtn) { 128 case CSSMERR_CSSM_MEMORY_ERROR: 129 crtn = CSSMERR_CSP_MEMORY_ERROR; 130 break; 131 default: 132 break; 133 } 134 CssmError::throwMe(crtn); 135 } 136} 137#endif /* BSAFE_CSP_ENABLE */ 138