예제 #1
0
SecSymmetricKeyRef
WRAP_PubUnwrapSymKey(SecPrivateKeyRef privkey, CSSM_DATA_PTR encKey, SECOidTag bulkalgtag)
{
    CFDataRef encryptedKey = NULL, bulkkey = NULL;
    CFMutableDictionaryRef keyparams = NULL;
    CFStringRef keyType = NULL;
    CFErrorRef error = NULL;
    SecSymmetricKeyRef bk = NULL;

    /* decrypt the key */
    encryptedKey = CFDataCreate(NULL, encKey->Data, encKey->Length);
    if (!encryptedKey) {
        goto out;
    }

    bulkkey = SecKeyCreateDecryptedData(privkey, kSecKeyAlgorithmRSAEncryptionPKCS1, encryptedKey, &error);
    if (!bulkkey) {
        goto out;
    }

    /* create the SecSymmetricKeyRef */
    keyType = SECOID_CopyKeyTypeByTag(bulkalgtag);
    if (!keyType) {
        goto out;
    }

    keyparams = CFDictionaryCreateMutable(NULL, 1,
                                          &kCFTypeDictionaryKeyCallBacks,
                                          &kCFTypeDictionaryValueCallBacks);
    if (!keyparams) {
        goto out;
    }

    CFDictionaryAddValue(keyparams, kSecAttrKeyType, keyType);
    bk = SecKeyCreateFromData(keyparams, bulkkey, NULL);

out:
    if (encryptedKey) { CFRelease(encryptedKey); }
    if (bulkkey) { CFRelease(bulkkey); }
    if (keyparams) { CFRelease(keyparams); }
    if (keyType) { CFRelease(keyType); }
    SEC_PrintCFError(error);
    return bk;
}
static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale)
{
    static const uint8_t salt[16] = { 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F };
    static const int saltLen = sizeof(salt);
    
    SecKeyRef theKey = NULL;
    uint8_t rawKeyData[RETURN_KEY_SIZE];
    
    CFIndex encodedAnswers = 0;
    CFIndex numAnswers = CFArrayGetCount(answers);
    const size_t concatenatedAnswersSize = MAXANSWERBUFF * numAnswers;
    
    char *concatenatedAnswers = (char *)malloc(concatenatedAnswersSize);
    if (concatenatedAnswers == NULL) {
        return NULL;
    }
    
    concatenatedAnswers[0] = 0; // NUL terminate
    
    int i;
    for (i = 0; i < numAnswers; i++) {
        CFMutableStringRef answer = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFArrayGetValueAtIndex(answers, i));
        if (answer) {
            secNormalize(answer, theLocale);
            
            CFIndex theAnswerLen = CFStringGetLength(answer);
            CFIndex theAnswerSize = CFStringGetMaximumSizeForEncoding(theAnswerLen, kCFStringEncodingUTF8);
            char *theAnswer = (char *)malloc(theAnswerSize + 1); // add space for NUL byte
            if (theAnswer) {
                if (theAnswerLen == CFStringGetBytes(answer, CFRangeMake(0, CFStringGetLength(answer)), kCFStringEncodingUTF8, '?', FALSE, (UInt8*)theAnswer, theAnswerSize, &theAnswerSize)) {
                    theAnswer[theAnswerSize] = 0; // NUL terminate
                    if (strlcat(concatenatedAnswers, theAnswer, concatenatedAnswersSize) < concatenatedAnswersSize) {
                        encodedAnswers += 1;
                    }
                }
                bzero(theAnswer, theAnswerSize);
                free(theAnswer);
            }
            CFRelease(answer);
        }
    }
    
    // one or more of the answers failed to encode
    if (encodedAnswers != numAnswers) {
        free(concatenatedAnswers);
        return NULL;
    }
    
    if (CCKeyDerivationPBKDF(kCCPBKDF2, concatenatedAnswers, strlen(concatenatedAnswers), salt, saltLen, kCCPRFHmacAlgSHA256, PBKDF_ROUNDS, rawKeyData, RETURN_KEY_SIZE)) {
        free(concatenatedAnswers);
        return NULL;
    }
    
    CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, rawKeyData, RETURN_KEY_SIZE);
    if (keyData) {
        CFMutableDictionaryRef params = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (params) {
            CFErrorRef error = NULL;
            CFDictionaryAddValue(params, kSecAttrKeyType, kSecAttrKeyTypeAES);
            theKey = SecKeyCreateFromData(params, keyData, &error);
            if (error) {
                CFRelease(error);
            }
            CFRelease(params);
        }
        CFRelease(keyData);
    }
    
    bzero(rawKeyData, RETURN_KEY_SIZE);
    bzero(concatenatedAnswers, concatenatedAnswersSize);
    free(concatenatedAnswers);
    return theKey;
}
예제 #3
0
int init_server_keys(bool ecdsa,
                     unsigned char *cert_der, size_t cert_der_len,
                     unsigned char *key_der, size_t key_der_len,
                     SSLCertificate *cert, tls_private_key_t *key)
{
    int err = 0;

    cert->next = NULL;
    cert->derCert.data = cert_der;
    cert->derCert.length = cert_der_len;

    SecKeyRef privKey = NULL;

#if TARGET_OS_IPHONE
    if(ecdsa)
    {
        privKey = SecKeyCreateECPrivateKey(kCFAllocatorDefault, key_der, key_der_len,
                                           kSecKeyEncodingPkcs1);
    } else {
        privKey = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, key_der, key_der_len,
                                            kSecKeyEncodingPkcs1);
    }

    require_action(privKey, fail, err=-1);
#else
    // Create the SecKeyRef
    CFErrorRef error = NULL;
    CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, key_der, key_der_len);
    CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    CFDictionarySetValue(parameters, kSecAttrKeyType, ecdsa?kSecAttrKeyTypeECDSA:kSecAttrKeyTypeRSA);
    CFDictionarySetValue(parameters, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
    privKey = SecKeyCreateFromData(parameters, keyData, &error);

    require_action(privKey, fail, err=(int)CFErrorGetCode(error));
#endif

    size_t keySize = SecKeyGetBlockSize(privKey);

    if(ecdsa) {
#if TARGET_OS_IPHONE
        /* Compute signature size from key size */
        size_t sigSize = 8+2*keySize;
#else
        size_t sigSize = keySize;
#endif
        require((*key = tls_private_key_ecdsa_create(privKey, sigSize,
                                                     SecECKeyGetNamedCurve(privKey), mySSLPrivKeyECDSA_sign)), fail);
    } else {
        require((*key = tls_private_key_rsa_create(privKey, keySize,
                                                   mySSLPrivKeyRSA_sign, mySSLPrivKeyRSA_decrypt)), fail);
    }

    err = 0;

fail:
#if !TARGET_OS_IPHONE
    CFReleaseSafe(parameters);
    CFReleaseSafe(keyData);
    CFReleaseSafe(error);
#endif

    return err;
}