]> git.saurik.com Git - apple/security.git/blobdiff - sec/Security/SecRSAKey.c
Security-55471.14.4.tar.gz
[apple/security.git] / sec / Security / SecRSAKey.c
index a8361811c0f86bbce8780622630554b0d538bef9..51bb520793613a653f30a322a27dc92cc06ac26b 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * 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,
  * 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@
  */
 
-/* 
+/*
  * SecRSAKey.c - CoreFoundation based rsa key object
  */
 
@@ -40,7 +40,8 @@
 #include <CoreFoundation/CFNumber.h>
 #include <Security/SecFramework.h>
 #include <Security/SecRandom.h>
-#include <security_utilities/debugging.h>
+#include <utilities/debugging.h>
+#include <utilities/SecCFWrappers.h>
 #include "SecItemPriv.h"
 #include <Security/SecInternal.h>
 
@@ -71,10 +72,10 @@ static void ccn_c_dump(cc_size count, const cc_unit *s)
     cc_size ix;
     for (ix = count; ix--;) {
         printf("0x%.02x, 0x%.02x, 0x%.02x, 0x%.02x, ",
-               (s[ix] >> 24) & 0xFF,
-               (s[ix] >> 16) & 0xFF,
-               (s[ix] >> 8 ) & 0xFF,
-               (s[ix] >> 0 ) & 0xFF);
+               (int) ((s[ix] >> 24) & 0xFF),
+               (int) ((s[ix] >> 16) & 0xFF),
+               (int) ((s[ix] >> 8 ) & 0xFF),
+               (int) ((s[ix] >> 0 ) & 0xFF));
     }
     printf("};");
 }
@@ -92,7 +93,7 @@ void ccrsa_dump_full_key(ccrsa_full_ctx_t key) {
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t d[]  = ", ccrsa_ctx_d(key));
-
+    
     printf("cc_size np = %lu;\n", cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
     ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))),     "uint8_t p[]  = ",
                cczp_prime(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
@@ -117,7 +118,7 @@ void ccrsa_dump_public_key(ccrsa_pub_ctx_t key) {
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t m[]  = ", ccrsa_ctx_m(key));
     ccn_cprint(ccrsa_ctx_n(key) + 1,  "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
     ccn_cprint(ccrsa_ctx_n(key),      "uint8_t e[]  = ", ccrsa_ctx_e(key));
-
+    
     printf("--\n");
 }
 
@@ -146,16 +147,16 @@ static int ccrsa_pub_init(ccrsa_pub_ctx_t pubkey,
                           size_t e_size, const uint8_t* e)
 {
     cc_skip_zeros(m_size, m);
-
+    
     cc_size nm = ccn_nof_size(m_size);
     if (nm > ccrsa_ctx_n(pubkey))
         return -1;
-
+    
     ccrsa_ctx_n(pubkey) = nm;
-
+    
     ccn_read_uint(nm, ccrsa_ctx_m(pubkey), m_size, m);
     cczp_init(ccrsa_ctx_zm(pubkey));
-
+    
     return ccn_read_uint(nm, ccrsa_ctx_e(pubkey), e_size, e);
 }
 
@@ -163,22 +164,22 @@ static int ccrsa_pub_init(ccrsa_pub_ctx_t pubkey,
 static OSStatus ccrsa_pub_decode(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyPKCS1 decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
@@ -186,25 +187,25 @@ errOut:
 static OSStatus ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAPubKeyApple decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     // We could honor the recipricol, but we don't think this is used enough to care.
     // Don't bother exploding the below function to try to handle this case, it computes.
-
+    
     require_noerr(ccrsa_pub_init(pubkey,
                                  decodedKey.modulus.length, decodedKey.modulus.data,
                                  decodedKey.pubExponent.length, decodedKey.pubExponent.data),
                   errOut);
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
@@ -214,90 +215,90 @@ static void ccasn_encode_int(cc_size n, const cc_unit*s, size_t s_size, uint8_t
 {
     **buffer = ASN1_INTEGER;
     *buffer += 1;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(s_size, *buffer, &itemLength);
     *buffer += itemLength;
-
+    
     ccn_write_int(n, s, s_size, *buffer);
-
+    
     *buffer += s_size;
 }
 
 
 static OSStatus SecRSAPublicKeyInit(SecKeyRef key,
-    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
-
+                                    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+    
     OSStatus result = errSecParam;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     // Set maximum size for parsers
     ccrsa_ctx_n(pubkey) = ccn_nof(kMaximumRSAKeyBits);
-
+    
     switch (encoding) {
-    case kSecKeyEncodingBytes: // Octets is PKCS1
-    case kSecKeyEncodingPkcs1:
-        result = ccrsa_pub_decode(pubkey, keyDataLength, keyData);
-        break;
-    case kSecKeyEncodingApplePkcs1:
-        result = ccrsa_pub_decode_apple(pubkey, keyDataLength, keyData);
-        break;
-    case kSecKeyEncodingRSAPublicParams:
-    {
-        SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
-
-        require_noerr(ccrsa_pub_init(pubkey,
-                       params->modulusLength, params->modulus,
-                       params->exponentLength, params->exponent), errOut);
-
-        result = errSecSuccess;
-        break;
-    }
-    case kSecExtractPublicFromPrivate:
-    {
-        ccrsa_full_ctx_t fullKey;
-        fullKey.full = (ccrsa_full_ctx*) keyData;
-
-        cc_size fullKeyN = ccrsa_ctx_n(fullKey);
-        require(fullKeyN <= ccrsa_ctx_n(pubkey), errOut);
-        memcpy(pubkey.pub, ccrsa_ctx_public(fullKey).pub, ccrsa_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
-        result = errSecSuccess;
-        break;
-    }
-    default:
-        break;
+        case kSecKeyEncodingBytes: // Octets is PKCS1
+        case kSecKeyEncodingPkcs1:
+            result = ccrsa_pub_decode(pubkey, keyDataLength, keyData);
+            break;
+        case kSecKeyEncodingApplePkcs1:
+            result = ccrsa_pub_decode_apple(pubkey, keyDataLength, keyData);
+            break;
+        case kSecKeyEncodingRSAPublicParams:
+        {
+            SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
+            
+            require_noerr(ccrsa_pub_init(pubkey,
+                                         params->modulusLength, params->modulus,
+                                         params->exponentLength, params->exponent), errOut);
+            
+            result = errSecSuccess;
+            break;
+        }
+        case kSecExtractPublicFromPrivate:
+        {
+            ccrsa_full_ctx_t fullKey;
+            fullKey.full = (ccrsa_full_ctx*) keyData;
+            
+            cc_size fullKeyN = ccrsa_ctx_n(fullKey);
+            require(fullKeyN <= ccrsa_ctx_n(pubkey), errOut);
+            memcpy(pubkey.pub, ccrsa_ctx_public(fullKey).pub, ccrsa_pub_ctx_size(ccn_sizeof_n(fullKeyN)));
+            result = errSecSuccess;
+            break;
+        }
+        default:
+            break;
     }
-
+    
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
-    const uint8_t *signedData, size_t signedDataLen,
-    const uint8_t *sig, size_t sigLen) {
+                                         const uint8_t *signedData, size_t signedDataLen,
+                                         const uint8_t *sig, size_t sigLen) {
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
-
+    
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, sigLen, sig);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
-
+    
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros as long as s is bigger than signedData.
             while (((ptrdiff_t)signedDataLen < (sEnd - sBytes)) && (*sBytes == 0))
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
@@ -309,16 +310,16 @@ static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
-
+            
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_SIGN, errOut);
-
+            
             while (*sBytes == 0xFF) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
@@ -326,45 +327,47 @@ static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
         case kSecPaddingOAEP:
             result = errSecParam;
             goto errOut;
-
+            
         default:
             result = errSecUnimplemented;
             goto errOut;
     }
-
+    
     // Compare the rest.
     require_quiet((sEnd - sBytes) == (ptrdiff_t)signedDataLen, errOut);
     require_quiet(memcmp(sBytes, signedData, signedDataLen) == 0, errOut);
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     cc_zero(ccrsa_ctx_n(pubkey), s);
-
+    
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
-    const uint8_t *plainText, size_t plainTextLen,
-       uint8_t *cipherText, size_t *cipherTextLen) {
+                                          const uint8_t *plainText, size_t plainTextLen,
+                                          uint8_t *cipherText, size_t *cipherTextLen) {
     OSStatus result = errSecParam;
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
     const size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
-
+    
     require(cipherTextLen, errOut);
     require(*cipherTextLen >= m_size, errOut);
-
+    
     uint8_t* sBytes = (uint8_t*) s;
-
+    
     switch (padding) {
         case kSecPaddingNone:
+            // We'll allow modulus size assuming input is smaller than modulus
+            require_quiet(plainTextLen <= m_size, errOut);
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(pubkey), s, plainTextLen, plainText), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(pubkey), s, ccrsa_ctx_m(pubkey)) < 0, errOut);
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
@@ -372,90 +375,90 @@ static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
-
-            require_quiet(plainTextLen < m_size - kMinimumPadding, errOut);
-
+            
+            require_quiet(plainTextLen <= m_size - kMinimumPadding, errOut);
+            
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
             
             while (prefix_zeros--)
-                 *sBytes++ = 0x00;
-
-           size_t pad_size = m_size - plainTextLen;
-
+                *sBytes++ = 0x00;
+            
+            size_t pad_size = m_size - plainTextLen;
+            
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_ENCRYPT;
-
+            
             ccrng_generate(ccrng_seckey, pad_size - 3, sBytes);
             // Remove zeroes from the random pad
-
+            
             const uint8_t* sEndOfPad = sBytes + (pad_size - 3);
             while (sBytes < sEndOfPad)
             {
                 if (*sBytes == 0x00)
                     *sBytes = 0xFF; // Michael said 0xFF was good enough.
-
+                
                 ++sBytes;
             }
-
+            
             *sBytes++ = 0x00;
-
+            
             memcpy(sBytes, plainText, plainTextLen);
-
+            
             ccn_swap(ccrsa_ctx_n(pubkey), s);
             break;
         }
         case kSecPaddingOAEP:
         {
             const struct ccdigest_info* di = ccsha1_di();
-
+            
             const size_t encodingOverhead = 2 + 2 * di->output_size;
-
+            
             require_action(m_size > encodingOverhead, errOut, result = errSecParam);
-            require_action_quiet(plainTextLen < m_size - encodingOverhead, errOut, result = errSSLCrypto);
-
+            require_action_quiet(plainTextLen <= m_size - encodingOverhead, errOut, result = errSecParam);
+            
             require_noerr_action(ccrsa_oaep_encode(di,
                                                    ccrng_seckey,
                                                    m_size, s,
                                                    plainTextLen, plainText), errOut, result = errSecInternal);
-           break;
+            break;
         }
         default:
             goto errOut;
     }
-
-
+    
+    
     ccrsa_pub_crypt(pubkey, s, s);
-
+    
     ccn_write_uint_padded(ccrsa_ctx_n(pubkey), s, m_size, cipherText);
     *cipherTextLen = m_size;
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
     return result;
 }
 
 static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
-       const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) {
+                                          const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) {
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     cc_unit s[ccrsa_ctx_n(pubkey)];
-
+    
     require_action_quiet(cipherText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainText != NULL, errOut, result = errSecParam);
     require_action_quiet(plainTextLen != NULL, errOut, result = errSecParam);
-
+    
     ccn_read_uint(ccrsa_ctx_n(pubkey), s, cipherTextLen, cipherText);
     ccrsa_pub_crypt(pubkey, s, s);
     ccn_swap(ccrsa_ctx_n(pubkey), s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
-
+    
     switch (padding) {
         case kSecPaddingNone:
             // Skip leading zeros
@@ -464,7 +467,7 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Verify and skip PKCS1 padding:
@@ -476,19 +479,19 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             
             while (prefix_zeros--)
                 require_quiet(*sBytes++ == 0x00, errOut);
-
+            
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
-
+            
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 0xFFs
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
-
+            
             break;
         }
         case kSecPaddingOAEP:
@@ -496,25 +499,25 @@ static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
-
+    
     // Return the rest.
     require_action((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut, result = errSecParam);
-
+    
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(pubkey), s);
-
+    
     return result;
 }
 
 static size_t SecRSAPublicKeyBlockSize(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     return ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
 }
 
@@ -523,30 +526,30 @@ static CFDataRef SecRSAPublicKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_pub_
 {
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
-
+    
     const size_t seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
-                            DERLengthOfItem(ASN1_INTEGER, e_size);
-
+    DERLengthOfItem(ASN1_INTEGER, e_size);
+    
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
-
+    
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
-
+    
     if (pkcs1 == NULL)
         return NULL;
-
+    
        CFDataSetLength(pkcs1, result_size);
-
+    
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
-
+    
     *bytes++ = ASN1_CONSTR_SEQUENCE;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
-
+    
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey), e_size, &bytes);
-
+    
     return pkcs1;
 }
 
@@ -554,10 +557,10 @@ static OSStatus SecRSAPublicKeyCopyPublicSerialization(SecKeyRef key, CFDataRef*
 {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, pubkey);
-
+    
     if (NULL == *serialized)
         return errSecDecode;
     else
@@ -568,6 +571,28 @@ static CFDictionaryRef SecRSAPublicKeyCopyAttributeDictionary(SecKeyRef key) {
     return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeRSA);
 }
 
+static CFStringRef SecRSAPublicKeyCopyDescription(SecKeyRef key) {
+    
+    CFStringRef keyDescription = NULL;
+    CFDataRef modRef = SecKeyCopyModulus(key);
+    
+    ccrsa_pub_ctx_t pubkey;
+    pubkey.pub = key->key;
+    
+    CFStringRef modulusString = CFDataCopyHexString(modRef);
+    require( modulusString, fail);
+    
+    keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, exponent: {hex: %llx, decimal: %lld}, modulus: %@, addr: %p>"), SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), (long long)*ccrsa_ctx_e(pubkey), (long long)*ccrsa_ctx_e(pubkey), modulusString, key);
+    
+fail:
+    CFReleaseSafe(modRef);
+    CFReleaseSafe(modulusString);
+       if(!keyDescription)
+               keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), (long)SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+       
+       return keyDescription;
+}
+
 SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPublicKey",
@@ -581,53 +606,54 @@ SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecRSAPublicKeyBlockSize,
        SecRSAPublicKeyCopyAttributeDictionary,
+    SecRSAPublicKeyCopyDescription,
     NULL,
     SecRSAPublicKeyCopyPublicSerialization,
 };
 
 /* Public Key API functions. */
 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
-    const uint8_t *keyData, CFIndex keyDataLength,
-    SecKeyEncoding encoding) {
+                                   const uint8_t *keyData, CFIndex keyDataLength,
+                                   SecKeyEncoding encoding) {
     return SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor, keyData,
-        keyDataLength, encoding);
+                        keyDataLength, encoding);
 }
 
 CFDataRef SecKeyCopyModulus(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef modulusData = CFDataCreateMutable(allocator, m_size);
-
+    
     if (modulusData == NULL)
         return NULL;
-
+    
        CFDataSetLength(modulusData, m_size);
-
+    
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, CFDataGetMutableBytePtr(modulusData));
-
+    
     return modulusData;
 }
 
 CFDataRef SecKeyCopyExponent(SecKeyRef key) {
     ccrsa_pub_ctx_t pubkey;
     pubkey.pub = key->key;
-
+    
     size_t e_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
        CFMutableDataRef exponentData = CFDataCreateMutable(allocator, e_size);
-
+    
     if (exponentData == NULL)
         return NULL;
-
+    
        CFDataSetLength(exponentData, e_size);
-
+    
     ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), e_size, CFDataGetMutableBytePtr(exponentData));
-
+    
     return exponentData;
 }
 
@@ -654,10 +680,10 @@ static int ccrsa_priv_init(ccrsa_priv_ctx_t privkey,
                            size_t qinv_size, const uint8_t* qinv)
 {
     int result = -1;
-
+    
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
-
+    
     if (ccn_read_uint(np, CCZP_PRIME(ccrsa_ctx_private_zp(privkey)), p_size, p))
         goto errOut;
     cczp_init(ccrsa_ctx_private_zp(privkey));
@@ -665,19 +691,19 @@ static int ccrsa_priv_init(ccrsa_priv_ctx_t privkey,
         goto errOut;
     if (ccn_read_uint(np, ccrsa_ctx_private_qinv(privkey), qinv_size, qinv))
         goto errOut;
-
+    
     if (ccn_read_uint(nq, CCZP_PRIME(ccrsa_ctx_private_zq(privkey)), q_size, q))
         goto errOut;
-
+    
     nq = ccn_n(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
     CCZP_N(ccrsa_ctx_private_zq(privkey)) = nq;
-
+    
     cczp_init(ccrsa_ctx_private_zq(privkey));
     if (ccn_read_uint(nq, ccrsa_ctx_private_dq(privkey), dq_size, dq))
         goto errOut;
-
+    
     result = 0;
-
+    
 errOut:
     return result;
 }
@@ -686,15 +712,15 @@ errOut:
 static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, const uint8_t* pkcs1)
 {
     OSStatus result = errSecParam;
-
+    
        DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
     DERRSAKeyPair decodedKey;
-
+    
        require_noerr_action(DERParseSequence(&keyItem,
                                           DERNumRSAKeyPairItemSpecs, DERRSAKeyPairItemSpecs,
                                           &decodedKey, sizeof(decodedKey)),
                          errOut, result = errSecDecode);
-
+    
     require_noerr(ccrsa_pub_init(fullkey,
                                  decodedKey.n.length, decodedKey.n.data,
                                  decodedKey.e.length, decodedKey.e.data),
@@ -705,34 +731,34 @@ static OSStatus ccrsa_full_decode(ccrsa_full_ctx_t fullkey, size_t pkcs1_size, c
         ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
         CCZP_N(ccrsa_ctx_private_zp(privkey)) = ccn_nof((ccn_bitsof_n(ccrsa_ctx_n(fullkey)) / 2) + 1);
         CCZP_N(ccrsa_ctx_private_zq(privkey)) = cczp_n(ccrsa_ctx_private_zp(privkey));
-
+        
         // TODO: Actually remember decodedKey.d.
-
+        
         require_noerr(ccrsa_priv_init(privkey,
-                                     decodedKey.p.length, decodedKey.p.data,
+                                      decodedKey.p.length, decodedKey.p.data,
                                       decodedKey.q.length, decodedKey.q.data,
                                       decodedKey.dp.length, decodedKey.dp.data,
                                       decodedKey.dq.length, decodedKey.dq.data,
                                       decodedKey.qInv.length, decodedKey.qInv.data),
                       errOut);
     }
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
-    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
+                                     const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
     OSStatus result = errSecParam;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     // Set maximum size for parsers
     ccrsa_ctx_n(fullkey) = ccn_nof(kMaximumRSAKeyBits);
-
+    
     switch (encoding) {
         case kSecKeyEncodingBytes: // Octets is PKCS1
         case kSecKeyEncodingPkcs1:
@@ -741,15 +767,15 @@ static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
         case kSecGenerateKey:
         {
             CFDictionaryRef parameters = (CFDictionaryRef) keyData;
-
+            
             CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
             CFIndex keyLengthInBits = getIntValue(ksize);
-
+            
             if (keyLengthInBits < 256 || keyLengthInBits > kMaximumRSAKeyBits) {
                 secwarning("Invalid or missing key size in: %@", parameters);
                 return errSecKeySizeNotAllowed;
             }
-
+            
             /* TODO: Add support for kSecPublicExponent parameter. */
             static uint8_t e[] = { 0x01, 0x00, 0x01 }; // Default is 65537
             if (!ccrsa_generate_key(keyLengthInBits, fullkey.full, sizeof(e), e, ccrng_seckey))
@@ -759,33 +785,35 @@ static OSStatus SecRSAPrivateKeyInit(SecKeyRef key,
         default:
             break;
     }
-
+    
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
-    const uint8_t *dataToSign, size_t dataToSignLen,
-    uint8_t *sig, size_t *sigLen) {
-
+                                        const uint8_t *dataToSign, size_t dataToSignLen,
+                                        uint8_t *sig, size_t *sigLen) {
+    
     OSStatus result = errSecParam;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     cc_unit s[ccrsa_ctx_n(fullkey)];
-
+    
     uint8_t* sBytes = (uint8_t*) s;
-
+    
     require(sigLen, errOut);
     require(*sigLen >= m_size, errOut);
-
+    
     switch (padding) {
         case kSecPaddingNone:
+            // We'll allow modulus size assuming input is smaller than modulus
+            require_quiet(dataToSignLen <= m_size, errOut);
             require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(fullkey), s, dataToSignLen, dataToSign), errOut);
             require_quiet(ccn_cmp(ccrsa_ctx_n(fullkey), s, ccrsa_ctx_m(fullkey)) < 0, errOut);
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             // Create PKCS1 padding:
@@ -793,29 +821,29 @@ static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
             // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData
             //
             const int kMinimumPadding = 1 + 1 + 8 + 1;
-
-            require(dataToSignLen < m_size - kMinimumPadding, errOut);
-
+            
+            require_quiet(dataToSignLen <= m_size - kMinimumPadding, errOut);
+            
             size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size;
             
             while (prefix_zeros--)
                 *sBytes++ = 0x00;
             
             size_t pad_size = m_size - dataToSignLen;
-
+            
             *sBytes++ = 0x00;
             *sBytes++ = RSA_PKCS1_PAD_SIGN;
-
+            
             size_t ff_size;
             for(ff_size = pad_size - 3; ff_size > 0; --ff_size)
                 *sBytes++ = 0xFF;
-
+            
             *sBytes++ = 0x00;
-
+            
             // Get the user data into s looking like a ccn.
             memcpy(sBytes, dataToSign, dataToSignLen);
             ccn_swap(ccrsa_ctx_n(fullkey), s);
-
+            
             break;
         }
         case kSecPaddingOAEP:
@@ -823,41 +851,41 @@ static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
-
+    
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
-
+    
     // Pad with leading zeros to fit in modulus size
     ccn_write_uint_padded(ccrsa_ctx_n(fullkey), s, m_size, sig);
     *sigLen = m_size;
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     ccn_zero(ccrsa_ctx_n(fullkey), s);
     return result;
 }
 
 static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
-       const uint8_t *cipherText, size_t cipherTextLen,
-       uint8_t *plainText, size_t *plainTextLen) {
+                                           const uint8_t *cipherText, size_t cipherTextLen,
+                                           uint8_t *plainText, size_t *plainTextLen) {
     OSStatus result = errSSLCrypto;
-
+    
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
-
+    
     cc_unit s[ccrsa_ctx_n(fullkey)];
     uint8_t recoveredData[ccn_sizeof_n(ccrsa_ctx_n(fullkey))];
-
+    
     ccn_read_uint(ccrsa_ctx_n(fullkey), s, cipherTextLen, cipherText);
     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
-
+    
     const uint8_t* sBytes = (uint8_t*) s;
     const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(fullkey));
-
+    
     require(plainTextLen, errOut);
-
+    
     switch (padding) {
         case kSecPaddingNone:
             ccn_swap(ccrsa_ctx_n(fullkey), s);
@@ -865,7 +893,7 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             while (sBytes < sEnd && *sBytes == 0x00)
                 ++sBytes;
             break;
-
+            
         case kSecPaddingPKCS1:
         {
             ccn_swap(ccrsa_ctx_n(fullkey), s);
@@ -881,13 +909,13 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
             
             require_quiet(*sBytes++ == 0x00, errOut);
             require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
-
+            
             while (*sBytes != 0x00) {
                 require_quiet(++sBytes < sEnd, errOut);
             }
             // Required to have at least 8 non-zeros
             require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
-
+            
             require_quiet(*sBytes == 0x00, errOut);
             require_quiet(++sBytes < sEnd, errOut);
             break;
@@ -895,11 +923,12 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         case kSecPaddingOAEP:
         {
             size_t length = sizeof(recoveredData);
-
+            
             require_noerr_quiet(ccrsa_oaep_decode(ccsha1_di(),
-                                                  ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s,
-                                                  &length, recoveredData), errOut);
-
+                                                                                                 &length, recoveredData,
+                                                  ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s
+                                                  ), errOut);
+            
             sBytes = recoveredData;
             sEnd = recoveredData + length;
             break;
@@ -907,87 +936,87 @@ static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
         default:
             goto errOut;
     }
-
+    
     require((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut);
     *plainTextLen = sEnd - sBytes;
     memcpy(plainText, sBytes, *plainTextLen);
-
+    
     result = errSecSuccess;
-
+    
 errOut:
     bzero(recoveredData, sizeof(recoveredData));
     ccn_zero(ccrsa_ctx_n(fullkey), s);
-
+    
     return result;
 }
 
 static size_t SecRSAPrivateKeyBlockSize(SecKeyRef key) {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
     return ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
 }
 
 static CFDataRef SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_full_ctx_t fullkey)
 {
     ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
-
+    
     const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
     const cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
-
+    
     size_t m_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
     size_t e_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey));
     size_t d_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey));
-
+    
     size_t p_size = ccn_write_int_size(np, cczp_prime(ccrsa_ctx_private_zp(privkey)));
     size_t q_size = ccn_write_int_size(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
-
+    
     size_t dp_size = ccn_write_int_size(np, ccrsa_ctx_private_dp(privkey));
     size_t dq_size = ccn_write_int_size(nq, ccrsa_ctx_private_dq(privkey));
-
+    
     size_t qinv_size = ccn_write_int_size(np, ccrsa_ctx_private_qinv(privkey));
-
+    
     const size_t seq_size = 3 +
-                            DERLengthOfItem(ASN1_INTEGER, m_size) +
-                            DERLengthOfItem(ASN1_INTEGER, e_size) +
-                            DERLengthOfItem(ASN1_INTEGER, d_size) +
-                            DERLengthOfItem(ASN1_INTEGER, p_size) +
-                            DERLengthOfItem(ASN1_INTEGER, q_size) +
-                            DERLengthOfItem(ASN1_INTEGER, dp_size) +
-                            DERLengthOfItem(ASN1_INTEGER, dq_size) +
-                            DERLengthOfItem(ASN1_INTEGER, qinv_size);
-
+    DERLengthOfItem(ASN1_INTEGER, m_size) +
+    DERLengthOfItem(ASN1_INTEGER, e_size) +
+    DERLengthOfItem(ASN1_INTEGER, d_size) +
+    DERLengthOfItem(ASN1_INTEGER, p_size) +
+    DERLengthOfItem(ASN1_INTEGER, q_size) +
+    DERLengthOfItem(ASN1_INTEGER, dp_size) +
+    DERLengthOfItem(ASN1_INTEGER, dq_size) +
+    DERLengthOfItem(ASN1_INTEGER, qinv_size);
+    
     const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
-
+    
        CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
-
+    
     if (pkcs1 == NULL)
         return NULL;
-
+    
        CFDataSetLength(pkcs1, result_size);
-
+    
     uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
-
+    
     *bytes++ = ASN1_CONSTR_SEQUENCE;
-
+    
     DERSize itemLength = 4;
     DEREncodeLength(seq_size, bytes, &itemLength);
     bytes += itemLength;
-
+    
     *bytes++ = ASN1_INTEGER;
     *bytes++ = 0x01;
     *bytes++ = 0x00;
-
+    
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey), m_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey), e_size, &bytes);
     ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), d_size, &bytes);
-
+    
     ccasn_encode_int(np, cczp_prime(ccrsa_ctx_private_zp(privkey)), p_size, &bytes);
     ccasn_encode_int(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)), q_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_dp(privkey), dp_size, &bytes);
     ccasn_encode_int(nq, ccrsa_ctx_private_dq(privkey), dq_size, &bytes);
     ccasn_encode_int(np, ccrsa_ctx_private_qinv(privkey), qinv_size, &bytes);
-
+    
     return pkcs1;
 }
 
@@ -995,7 +1024,7 @@ static CFDataRef SecRSAPrivateKeyCopyPKCS1(SecKeyRef key)
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     return SecRSAPrivateKeyCreatePKCS1(allocator, fullkey);
 }
@@ -1004,10 +1033,10 @@ static OSStatus SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key, CFDataRef
 {
     ccrsa_full_ctx_t fullkey;
     fullkey.full = key->key;
-
+    
        CFAllocatorRef allocator = CFGetAllocator(key);
     *serialized = SecRSAPublicKeyCreatePKCS1(allocator, fullkey);
-
+    
     if (NULL == *serialized)
         return errSecDecode;
     else
@@ -1018,19 +1047,24 @@ static OSStatus SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key, CFDataRef
 static CFDictionaryRef SecRSAPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
        CFDictionaryRef dict = NULL;
        CFDataRef fullKeyBlob = NULL;
-
+    
        /* PKCS1 encode the key pair. */
        fullKeyBlob = SecRSAPrivateKeyCopyPKCS1(key);
     require(fullKeyBlob, errOut);
-
+    
        dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeRSA, fullKeyBlob);
-
+    
 errOut:
        CFReleaseSafe(fullKeyBlob);
-
+    
        return dict;
 }
 
+static CFStringRef SecRSAPrivateKeyCopyDescription(SecKeyRef key){
+    
+       return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), SecKeyGetAlgorithmID(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
+    
+}
 SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
     kSecKeyDescriptorVersion,
     "RSAPrivateKey",
@@ -1044,37 +1078,38 @@ SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
     NULL, /* SecKeyComputeMethod */
     SecRSAPrivateKeyBlockSize,
        SecRSAPrivateKeyCopyAttributeDictionary,
+    SecRSAPrivateKeyCopyDescription,
     NULL,
     SecRSAPrivateKeyCopyPublicSerialization,
 };
 
 /* Private Key API functions. */
 SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator,
-    const uint8_t *keyData, CFIndex keyDataLength,
-    SecKeyEncoding encoding) {
+                                    const uint8_t *keyData, CFIndex keyDataLength,
+                                    SecKeyEncoding encoding) {
     return SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor, keyData,
-        keyDataLength, encoding);
+                        keyDataLength, encoding);
 }
 
 
 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
-    SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey) {
+                               SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey) {
     OSStatus status = errSecParam;
-
+    
     CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
-
+    
     SecKeyRef pubKey = NULL;
     SecKeyRef privKey = SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor,
                                      (const void*) parameters, 0, kSecGenerateKey);
-
+    
     require(privKey, errOut);
-
+    
        /* Create SecKeyRef's from the pkcs1 encoded keys. */
     pubKey = SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor,
                           privKey->key, 0, kSecExtractPublicFromPrivate);
-
+    
     require(pubKey, errOut);
-
+    
     if (rsaPublicKey) {
         *rsaPublicKey = pubKey;
         pubKey = NULL;
@@ -1083,12 +1118,12 @@ OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
         *rsaPrivateKey = privKey;
         privKey = NULL;
     }
-
+    
     status = errSecSuccess;
-
+    
 errOut:
     CFReleaseSafe(pubKey);
     CFReleaseSafe(privKey);
-
+    
        return status;
 }