1/* 2 * Copyright (c) 2002-2009,2011-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 * 23 * SecKeyPriv.h - SPIs to SecKeyRef objects. 24 */ 25 26/*! 27 @header SecKeyPriv 28 The functions provided in SecKeyPriv.h implement and manage a particular 29 type of keychain item that represents a key. A key can be stored in a 30 keychain, but a key can also be a transient object. 31 32 You can use a key as a keychain item in most functions. 33*/ 34 35#ifndef _SECURITY_SECKEYPRIV_H_ 36#define _SECURITY_SECKEYPRIV_H_ 37 38#include <Security/SecKey.h> 39#include <Security/x509defs.h> 40#include <Security/SecAsn1Types.h> 41#include <AvailabilityMacros.h> 42 43#if defined(__cplusplus) 44extern "C" { 45#endif 46 47typedef struct SecRSAPublicKeyParams { 48 uint8_t *modulus; /* modulus */ 49 CFIndex modulusLength; 50 uint8_t *exponent; /* public exponent */ 51 CFIndex exponentLength; 52} SecRSAPublicKeyParams; 53 54typedef uint32_t SecKeyEncoding; 55enum { 56 /* Typically only used for symmetric keys. */ 57 kSecKeyEncodingRaw = 0, 58 59 /* RSA keys are DER-encoded according to PKCS1. */ 60 kSecKeyEncodingPkcs1 = 1, 61 62 /* RSA keys are DER-encoded according to PKCS1 with Apple Extensions. */ 63 kSecKeyEncodingApplePkcs1 = 2, 64 65 /* RSA public key in SecRSAPublicKeyParams format. keyData is a pointer 66 to a SecRSAPublicKeyParams and keyDataLength is 67 sizeof(SecRSAPublicKeyParams). */ 68 kSecKeyEncodingRSAPublicParams = 3, 69}; 70 71typedef OSStatus (*SecKeyInitMethod)(SecKeyRef, const uint8_t *, CFIndex, 72 SecKeyEncoding); 73typedef void *(*SecKeyCopyMethod)(SecKeyRef); 74typedef void (*SecKeyDestroyMethod)(SecKeyRef); 75typedef void (*SecKeyDeleteMethod)(SecKeyRef); 76typedef void (*SecKeyShowMethod)(SecKeyRef); 77typedef OSStatus (*SecKeyRawSignMethod)(SecKeyRef key, SecPadding padding, 78 const uint8_t *dataToSign, size_t dataToSignLen, 79 uint8_t *sig, size_t *sigLen); 80typedef OSStatus (*SecKeyRawVerifyMethod)( 81 SecKeyRef key, SecPadding padding, const uint8_t *signedData, 82 size_t signedDataLen, const uint8_t *sig, size_t sigLen); 83typedef OSStatus (*SecKeyEncryptMethod)(SecKeyRef key, SecPadding padding, 84 const uint8_t *plainText, size_t plainTextLen, 85 uint8_t *cipherText, size_t *cipherTextLen); 86typedef OSStatus (*SecKeyDecryptMethod)(SecKeyRef key, SecPadding padding, 87 const uint8_t *cipherText, size_t cipherTextLen, 88 uint8_t *plainText, size_t *plainTextLen); 89typedef size_t (*SecKeyBlockSizeMethod)(SecKeyRef key); 90typedef CFDictionaryRef (*SecKeyCopyDictionaryMethod)(SecKeyRef key); 91 92typedef struct { 93 const char *name; 94 SecKeyInitMethod init; 95 SecKeyCopyMethod copy; 96 SecKeyDestroyMethod destroy; 97 SecKeyDeleteMethod remove; 98 SecKeyShowMethod show; 99 SecKeyRawSignMethod rawSign; 100 SecKeyRawVerifyMethod rawVerify; 101 SecKeyEncryptMethod encrypt; 102 SecKeyDecryptMethod decrypt; 103 SecKeyBlockSizeMethod blockSize; 104 SecKeyCopyDictionaryMethod copyDictionary; 105 /* If known, the number of bytes to allocate for the key field in the SecKey struct. */ 106 int extraBytes; 107} SecKeyDescriptor; 108 109/*! 110 @function SecKeyGetAlgorithmID 111 @abstract Returns a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure for the given key. 112 @param key A key reference. 113 @param algid On return, a pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure. 114 @result A result code. See "Security Error Codes" (SecBase.h). 115*/ 116OSStatus SecKeyGetAlgorithmID(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER **algid) 117 DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER; 118 119enum { 120 kSecNullAlgorithmID = 0, 121 kSecRSAAlgorithmID = 1, 122 kSecDSAAlgorithmID = 2, /* unsupported, just here for reference. */ 123 kSecECDSAAlgorithmID = 3, 124}; 125 126/*! 127 @function SecKeyGetAlgorithmId 128 @abstract Returns an enumerated constant value which identifies the algorithm for the given key. 129 @param key A key reference. 130 @result An algorithm identifier. 131*/ 132CFIndex SecKeyGetAlgorithmId(SecKeyRef key) 133 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); 134 135/*! 136 @function SecKeyGetStrengthInBits 137 @abstract Returns key strength in bits for the given key. 138 @param key A key reference. 139 @param algid A pointer to a CSSM_X509_ALGORITHM_IDENTIFIER structure, as returned from a call to SecKeyGetAlgorithmID. 140 @param strength On return, the key strength in bits. 141 @result A result code. See "Security Error Codes" (SecBase.h). 142*/ 143OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength); 144 145/*! 146 @function SecKeyImportPair 147 @abstract Takes an asymmetric key pair and stores it in the keychain specified by the keychain parameter. 148 @param keychainRef A reference to the keychain in which to store the private and public key items. Specify NULL for the default keychain. 149 @param publicCssmKey A CSSM_KEY which is valid for the CSP returned by SecKeychainGetCSPHandle(). This may be a normal key or reference key. 150 @param privateCssmKey A CSSM_KEY which is valid for the CSP returned by SecKeychainGetCSPHandle(). This may be a normal key or reference key. 151 @param initialAccess A SecAccess object that determines the initial access rights to the private key. The public key is given an any/any acl by default. 152 @param publicKey Optional output pointer to the keychain item reference of the imported public key. The caller must call CFRelease on this value if it is returned. 153 @param privateKey Optional output pointer to the keychain item reference of the imported private key. The caller must call CFRelease on this value if it is returned. 154 @result A result code. See "Security Error Codes" (SecBase.h). 155 @deprecated in 10.5 and later. Use the SecKeychainItemImport function instead; see <Security/SecImportExport.h> 156*/ 157OSStatus SecKeyImportPair( 158 SecKeychainRef keychainRef, 159 const CSSM_KEY *publicCssmKey, 160 const CSSM_KEY *privateCssmKey, 161 SecAccessRef initialAccess, 162 SecKeyRef* publicKey, 163 SecKeyRef* privateKey) 164 DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; 165 166/*! 167 @function SecKeyCreate 168 @abstract Create a key reference from the supplied key data. 169 @param allocator CFAllocator to allocate the key data. Pass NULL to use the default allocator. 170 @param keyClass A descriptor for the particular class of key that is being created. 171 @param keyData Data from which to create the key. Specify the format of this data in the encoding parameter. 172 @param keyDataLength Length of the data pointed to by keyData. 173 @param encoding A value of type SecKeyEncoding which describes the format of keyData. 174 @result A key reference. 175 @discussion Warning: this function is NOT intended for use outside the Security stack in its current state. <rdar://3201885> 176 IMPORTANT: on Mac OS X 10.5 and earlier, the SecKeyCreate function had a different parameter list. 177 The current parameter list matches the iPhone OS implementation. Existing clients of this function 178 on Mac OS X (and there should not be any outside the Security stack, per the warning above) must 179 migrate to the replacement function, SecKeyCreateWithCSSMKey. 180*/ 181SecKeyRef SecKeyCreate(CFAllocatorRef allocator, 182 const SecKeyDescriptor *keyClass, const uint8_t *keyData, 183 CFIndex keyDataLength, SecKeyEncoding encoding); 184 185/*! 186 @function SecKeyCreateWithCSSMKey 187 @abstract Generate a temporary floating key reference for a CSSM_KEY. 188 @param key A pointer to a CSSM_KEY structure. 189 @param keyRef On return, a key reference. 190 @result A result code. See "Security Error Codes" (SecBase.h). 191 @discussion Warning: this function is NOT intended for use outside the Security stack in its current state. <rdar://3201885> 192*/ 193OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef); 194 195 196/*! 197 @function SecKeyRawSign 198 @abstract Given a private key and data to sign, generate a digital signature. 199 @param key Private key with which to sign. 200 @param padding See Padding Types above, typically kSecPaddingPKCS1SHA1. 201 @param dataToSign The data to be signed, typically the digest of the actual data. 202 @param dataToSignLen Length of dataToSign in bytes. 203 @param sig Pointer to buffer in which the signature will be returned. 204 @param sigLen IN/OUT maximum length of sig buffer on input, actualy length of sig on output. 205 @result A result code. See "Security Error Codes" (SecBase.h). 206 @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding 207 will be performed prior to signing. If this argument is kSecPaddingNone, 208 the incoming data will be signed "as is". 209 210 When PKCS1 padding is performed, the maximum length of data that can 211 be signed is the value returned by SecKeyGetBlockSize() - 11. 212 213 NOTE: The behavior this function with kSecPaddingNone is undefined if the 214 first byte of dataToSign is zero; there is no way to verify leading zeroes 215 as they are discarded during the calculation. 216 217 If you want to generate a proper PKCS1 style signature with DER encoding of 218 the digest type - and the dataToSign is a SHA1 digest - use kSecPaddingPKCS1SHA1. 219*/ 220OSStatus SecKeyRawSign( 221 SecKeyRef key, 222 SecPadding padding, 223 const uint8_t *dataToSign, 224 size_t dataToSignLen, 225 uint8_t *sig, 226 size_t *sigLen); 227 228 229/*! 230 @function SecKeyRawVerify 231 @abstract Given a public key, data which has been signed, and a signature, verify the signature. 232 @param key Public key with which to verify the signature. 233 @param padding See Padding Types above, typically kSecPaddingPKCS1SHA1. 234 @param signedData The data over which sig is being verified, typically the digest of the actual data. 235 @param signedDataLen Length of signedData in bytes. 236 @param sig Pointer to the signature to verify. 237 @param sigLen Length of sig in bytes. 238 @result A result code. See "Security Error Codes" (SecBase.h). 239 @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding 240 will be checked during verification. If this argument is kSecPaddingNone, 241 the incoming data will be compared directly to sig. 242 243 If you are verifying a proper PKCS1-style signature, with DER encoding of the digest 244 type - and the signedData is a SHA1 digest - use kSecPaddingPKCS1SHA1. 245*/ 246OSStatus SecKeyRawVerify( 247 SecKeyRef key, 248 SecPadding padding, 249 const uint8_t *signedData, 250 size_t signedDataLen, 251 const uint8_t *sig, 252 size_t sigLen); 253 254 255/*! 256 @function SecKeyEncrypt 257 @abstract Encrypt a block of plaintext. 258 @param key Public key with which to encrypt the data. 259 @param padding See Padding Types above, typically kSecPaddingPKCS1. 260 @param plainText The data to encrypt. 261 @param plainTextLen Length of plainText in bytes, this must be less 262 or equal to the value returned by SecKeyGetBlockSize(). 263 @param cipherText Pointer to the output buffer. 264 @param cipherTextLen On input, specifies how much space is available at 265 cipherText; on return, it is the actual number of cipherText bytes written. 266 @result A result code. See "Security Error Codes" (SecBase.h). 267 @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding 268 will be performed prior to encryption. If this argument is kSecPaddingNone, 269 the incoming data will be encrypted "as is". 270 271 When PKCS1 padding is performed, the maximum length of data that can 272 be encrypted is the value returned by SecKeyGetBlockSize() - 11. 273 274 When memory usage is a critical issue, note that the input buffer 275 (plainText) can be the same as the output buffer (cipherText). 276*/ 277OSStatus SecKeyEncrypt( 278 SecKeyRef key, 279 SecPadding padding, 280 const uint8_t *plainText, 281 size_t plainTextLen, 282 uint8_t *cipherText, 283 size_t *cipherTextLen); 284 285 286/*! 287 @function SecKeyDecrypt 288 @abstract Decrypt a block of ciphertext. 289 @param key Private key with which to decrypt the data. 290 @param padding See SecPadding types above; typically kSecPaddingPKCS1. 291 @param cipherText The data to decrypt. 292 @param cipherTextLen Length of cipherText in bytes; this must be less 293 or equal to the value returned by SecKeyGetBlockSize(). 294 @param plainText Pointer to the output buffer. 295 @param plainTextLen On input, specifies how much space is available at 296 plainText; on return, it is the actual number of plainText bytes written. 297 @result A result code. See "Security Error Codes" (SecBase.h). 298 @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding 299 will be removed after decryption. If this argument is kSecPaddingNone, 300 the decrypted data will be returned "as is". 301 302 When memory usage is a critical issue, note that the input buffer 303 (plainText) can be the same as the output buffer (cipherText). 304*/ 305OSStatus SecKeyDecrypt( 306 SecKeyRef key, /* Private key */ 307 SecPadding padding, /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */ 308 const uint8_t *cipherText, 309 size_t cipherTextLen, /* length of cipherText */ 310 uint8_t *plainText, 311 size_t *plainTextLen); /* IN/OUT */ 312 313OSStatus SecKeyVerifyDigest( 314 SecKeyRef key, /* Private key */ 315 const SecAsn1AlgId *algId, /* algorithm oid/params */ 316 const uint8_t *digestData, /* signature over this digest */ 317 size_t digestDataLen, /* length of dataToDigest */ 318 const uint8_t *sig, /* signature to verify */ 319 size_t sigLen); /* length of sig */ 320 321OSStatus SecKeySignDigest( 322 SecKeyRef key, /* Private key */ 323 const SecAsn1AlgId *algId, /* algorithm oid/params */ 324 const uint8_t *digestData, /* signature over this digest */ 325 size_t digestDataLen, /* length of digestData */ 326 uint8_t *sig, /* signature, RETURNED */ 327 size_t *sigLen); /* IN/OUT */ 328 329 330/* These are the named curves we support. These values come from RFC 4492 331 section 5.1.1, with the exception of SSL_Curve_None which means 332 "ECDSA not negotiated". */ 333typedef enum 334{ 335 kSecECCurveNone = -1, 336 kSecECCurveSecp256r1 = 23, 337 kSecECCurveSecp384r1 = 24, 338 kSecECCurveSecp521r1 = 25 339} SecECNamedCurve; 340 341/* Return a named curve enum for ecPrivateKey. */ 342SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef ecPrivateKey); 343CFDataRef SecECKeyCopyPublicBits(SecKeyRef key); 344 345/* Given an RSA public key in encoded form return a SecKeyRef representing 346 that key. Supported encodings are kSecKeyEncodingPkcs1. */ 347SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator, 348 const uint8_t *keyData, CFIndex keyDataLength, 349 SecKeyEncoding encoding); 350 351CFDataRef SecKeyCopyModulus(SecKeyRef rsaPublicKey); 352CFDataRef SecKeyCopyExponent(SecKeyRef rsaPublicKey); 353 354/*! 355 @function SecKeyCopyPublicBytes 356 @abstract Gets the bits of a public key 357 @param key Key to retrieve the bits. 358 @param publicBytes An out parameter to receive the public key bits 359 @result Errors if any when retrieving the public key bits.. 360 */ 361OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes); 362 363/*! 364 @function SecKeyCreatePublicFromPrivate 365 @abstract Create a public SecKeyRef from a private SecKeyRef 366 @param privateKey The private SecKeyRef for which you want the public key 367 @result A public SecKeyRef, or NULL if the conversion failed 368 @discussion This is a "best attempt" function, hence the SPI nature. If the public 369 key bits are not in memory, it attempts to load from the keychain. If the public 370 key was not tracked on the keychain, it will fail. 371*/ 372SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey); 373 374/*! 375 @function SecKeyCreateFromPublicData 376*/ 377SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes); 378 379OSStatus SecKeyRawVerifyOSX( 380 SecKeyRef key, 381 SecPadding padding, 382 const uint8_t *signedData, 383 size_t signedDataLen, 384 const uint8_t *sig, 385 size_t sigLen); 386 387#if defined(__cplusplus) 388} 389#endif 390 391#endif /* !_SECURITY_SECKEYPRIV_H_ */ 392 393