SecKeyPriv.h   [plain text]


/*
 * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
 * 
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

/*!
	@header SecKeyPriv
	The functions provided in SecKeyPriv.h implement and manage a particular
    type of keychain item that represents a key.  A key can be stored in a
    keychain, but a key can also be a transient object.

	You can use a key as a keychain item in most functions.
*/

#ifndef _SECURITY_SECKEYPRIV_H_
#define _SECURITY_SECKEYPRIV_H_

#include <Security/SecKey.h>
#include <Security/SecAsn1Types.h>
#include <CoreFoundation/CFRuntime.h>
#include <CoreFoundation/CFData.h>

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct __SecDERKey {
	uint8_t             *oid;
	CFIndex             oidLength;

	uint8_t             *parameters;
	CFIndex             parametersLength;

    /* Contents of BIT STRING in DER Encoding */
	uint8_t             *key;
	CFIndex             keyLength;
} SecDERKey;


typedef uint32_t SecKeyEncoding;
enum {
    /* Typically only used for symmetric keys. */
    kSecKeyEncodingRaw = 0,

    /* RSA keys are DER-encoded according to PKCS1. */
    kSecKeyEncodingPkcs1 = 1,

    /* RSA keys are DER-encoded according to PKCS1 with Apple Extensions. */
    kSecKeyEncodingApplePkcs1 = 2,

    /* RSA public key in SecRSAPublicKeyParams format.  keyData is a pointer
       to a SecRSAPublicKeyParams and keyDataLength is
       sizeof(SecRSAPublicKeyParams). */
    kSecKeyEncodingRSAPublicParams = 3,

    /* RSA public key in SecRSAPublicKeyParams format.  keyData is a pointer
       to a SecRSAPublicKeyParams and keyDataLength is
       sizeof(SecRSAPublicKeyParams). */
    kSecDERKeyEncoding = 4,

    /* Internal "encodings to send other data" */
    kSecGenerateKey = 5,
    kSecExtractPublicFromPrivate = 6,

    /* Encoding came from SecKeyCopyPublicBytes for a public key,
       or internally from a private key */
    kSecKeyEncodingBytes = 7,
};

typedef OSStatus (*SecKeyInitMethod)(SecKeyRef, const uint8_t *, CFIndex,
    SecKeyEncoding);
typedef void  (*SecKeyDestroyMethod)(SecKeyRef);
typedef OSStatus (*SecKeyRawSignMethod)(SecKeyRef key, SecPadding padding,
	const uint8_t *dataToSign, size_t dataToSignLen,
	uint8_t *sig, size_t *sigLen);
typedef OSStatus (*SecKeyRawVerifyMethod)(
    SecKeyRef key, SecPadding padding, const uint8_t *signedData,
    size_t signedDataLen, const uint8_t *sig, size_t sigLen);
typedef OSStatus (*SecKeyEncryptMethod)(SecKeyRef key, SecPadding padding,
    const uint8_t *plainText, size_t plainTextLen,
	uint8_t *cipherText, size_t *cipherTextLen);
typedef OSStatus (*SecKeyDecryptMethod)(SecKeyRef key, SecPadding padding,
    const uint8_t *cipherText, size_t cipherTextLen, 
    uint8_t *plainText, size_t *plainTextLen);
typedef OSStatus (*SecKeyComputeMethod)(SecKeyRef key,
    const uint8_t *pub_key, size_t pub_key_len,
    uint8_t *computed_key, size_t *computed_key_len);
typedef size_t (*SecKeyBlockSizeMethod)(SecKeyRef key);
typedef CFDictionaryRef (*SecKeyCopyDictionaryMethod)(SecKeyRef key);
typedef CFIndex (*SecKeyGetAlgorithmIDMethod)(SecKeyRef key);
typedef OSStatus (*SecKeyCopyPublicBytesMethod)(SecKeyRef key, CFDataRef *serailziation);


#define kSecKeyDescriptorVersion  (2)

typedef struct __SecKeyDescriptor {
    /* Version of this SecKeyDescriptor.  Must be kSecKeyDescriptorVersion. */
    uint32_t version;

    /* Name of this key class for use by SecKeyShow(). */
    const char *name;

    /* If nonzero, SecKeyCreate will allocate this many bytes for the key
       field in the SecKeyRef it creates.  If zero key is NULL and the
       implementor can choose to dynamically allocate it in the init
       function and free it in the destroy function.  */
    uint32_t extraBytes;

    /* Called by SecKeyCreate(). */
    SecKeyInitMethod init;
    /* Called by destructor (final CFRelease() or gc if using). */
    SecKeyDestroyMethod destroy;
    /* Called by SecKeyRawSign(). */
    SecKeyRawSignMethod rawSign;
    /* Called by SecKeyRawVerify(). */
    SecKeyRawVerifyMethod rawVerify;
    /* Called by SecKeyEncrypt(). */
    SecKeyEncryptMethod encrypt;
    /* Called by SecKeyDecrypt(). */
    SecKeyDecryptMethod decrypt;
    /* Reserved for future use. */
    SecKeyComputeMethod compute;
    /* Called by SecKeyGetBlockSize(). */
    SecKeyBlockSizeMethod blockSize;
    /* Called by SecKeyCopyAttributeDictionary(), which is private. */
    SecKeyCopyDictionaryMethod copyDictionary;
#if kSecKeyDescriptorVersion > 0
    /* Called by SecKeyCopyAttributeDictionary(), which is private. */
    SecKeyGetAlgorithmIDMethod getAlgorithmID;
#endif
#if kSecKeyDescriptorVersion > 1
    SecKeyCopyPublicBytesMethod copyPublic;
#endif
} SecKeyDescriptor;

struct __SecKey {
    CFRuntimeBase		_base;

    const SecKeyDescriptor *key_class;

    /* The actual key handled by class. */
    void *key;
};

/*!
    @function SecKeyCreate
    @abstract Given a private key and data to sign, generate a digital signature. 
    @param allocator allocator to use when allocating this key instance.
    @param key_class pointer to a SecKeyDescriptor.
    @param keyData The second argument to the init() function in the key_class.
    @param keyDataLength The third argument to the init() function in the key_class.
    @param encoding The fourth argument to the init() function in the key_class.
    @result A newly allocated SecKeyRef.  
 */
SecKeyRef SecKeyCreate(CFAllocatorRef allocator,
    const SecKeyDescriptor *key_class, const uint8_t *keyData,
	CFIndex keyDataLength, SecKeyEncoding encoding);

/* Create a public key from an oid, params and keyData all in DER format. */
SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator,
    const SecAsn1Oid *oid1, const SecAsn1Item *params,
    const SecAsn1Item *keyData);

/* Return an attribute dictionary used to store this item in a keychain. */
CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key);

/* Return a key from an attribute dictionary that was used to store this item
   in a keychain. */
SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes);

OSStatus SecKeyDigestAndVerify(
    SecKeyRef           key,            /* Public key */
	const SecAsn1AlgId  *algId,         /* algorithm oid/params */
	const uint8_t       *dataToDigest,	/* signature over this data */
	size_t              dataToDigestLen,/* length of dataToDigest */
	const uint8_t       *sig,			/* signature to verify */
	size_t              sigLen); 		/* length of sig */

OSStatus SecKeyDigestAndSign(
    SecKeyRef           key,            /* Private key */
	const SecAsn1AlgId  *algId,         /* algorithm oid/params */
	const uint8_t       *dataToDigest,	/* signature over this data */
	size_t              dataToDigestLen,/* length of dataToDigest */
	uint8_t             *sig,			/* signature, RETURNED */
	size_t              *sigLen);		/* IN/OUT */

OSStatus SecKeyVerifyDigest(
    SecKeyRef           key,            /* Private key */
    const SecAsn1AlgId  *algId,         /* algorithm oid/params */
    const uint8_t       *digestData,	/* signature over this digest */
    size_t              digestDataLen,/* length of dataToDigest */
    const uint8_t       *sig,			/* signature to verify */
    size_t              sigLen);        /* length of sig */

OSStatus SecKeySignDigest(
    SecKeyRef           key,            /* Private key */
    const SecAsn1AlgId  *algId,         /* algorithm oid/params */
    const uint8_t       *digestData,	/* signature over this digest */
    size_t              digestDataLen,/* length of digestData */
    uint8_t             *sig,			/* signature, RETURNED */
    size_t              *sigLen); 		/* IN/OUT */

OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* serializedPublic);
SecKeyRef SecKeyCreateFromPublicBytes(CFAllocatorRef allocator, CFIndex algorithmID, const uint8_t *keyData, CFIndex keyDataLength);
SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef serialized);


CFDictionaryRef SecKeyGeneratePrivateAttributeDictionary(SecKeyRef key,
                                                         CFTypeRef keyType,
                                                         CFDataRef privateBlob);
CFDictionaryRef SecKeyGeneratePublicAttributeDictionary(SecKeyRef key, CFTypeRef keyType);

enum {
    kSecNullAlgorithmID = 0,
    kSecRSAAlgorithmID = 1,
    kSecDSAAlgorithmID = 2,   /* unsupported, just here for reference. */
    kSecECDSAAlgorithmID = 3,
};

CFIndex SecKeyGetAlgorithmID(SecKeyRef key);

typedef enum {
    kSecKeyKeySizeInBits        = 0,
    kSecKeySignatureSize        = 1,
    kSecKeyEncryptedDataSize    = 2,
    // More might belong here, but we aren't settled on how
    // to take into account padding and/or digest types.
} SecKeySize;

/*!
 @function SecKeyGetSize
 @abstract Returns a size in bytes. 
 @param key The key for which the block length is requested.
 @param whichSize The size that you want evaluated.
 @result The block length of the key in bytes.
 @discussion If for example key is an RSA key the value returned by 
 this function is the size of the modulus.
 */
size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize)
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0);
    


#if defined(__cplusplus)
}
#endif

#endif /* !_SECURITY_SECKEYPRIV_H_ */