static int kc_rsa_sign(int type, const unsigned char *from, unsigned int flen, unsigned char *to, unsigned int *tlen, const RSA *rsa) { struct kc_rsa *kc = RSA_get_app_data(rk_UNCONST(rsa)); size_t sigLen = kc->keysize; SecPadding padding; OSStatus status; if (type == NID_md5) { padding = kSecPaddingPKCS1MD5; } else if (type == NID_sha1) { padding = kSecPaddingPKCS1SHA1; } else return -1; status = SecKeyRawSign(kc->pkey, padding, from, flen, to, &sigLen); if (status) return -2; *tlen = (unsigned int)sigLen; return 1; }
static int kc_rsa_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { struct kc_rsa *kc = RSA_get_app_data(rsa); size_t sigLen = kc->keysize; OSStatus status; if (padding != RSA_PKCS1_PADDING) return -1; status = SecKeyRawSign(kc->pkey, kSecPaddingPKCS1, from, flen, to, &sigLen); if (status) return -2; return (int)sigLen; }
static int mySSLPrivKeyECDSA_sign(void *key, const uint8_t *plaintext, size_t plaintextLen, uint8_t *sig, size_t *sigLen) { SecKeyRef keyRef = key; return SecKeyRawSign(keyRef, kSecPaddingPKCS1, plaintext, plaintextLen, sig, sigLen); }
static CFDataRef sosSignHash(SecKeyRef privkey, const struct ccdigest_info *di, uint8_t *hbuf) { OSStatus stat; size_t siglen = SIGLEN; uint8_t sig[siglen]; if((stat = SecKeyRawSign(privkey, kSecPaddingNone, hbuf, di->output_size, sig, &siglen)) != 0) { return NULL; } return CFDataCreate(NULL, sig, (CFIndex)siglen); }
/* Test basic add delete update copy matching stuff. */ static void tests(SecKeyDescriptor *descriptor) { const uint8_t *keyData = (const uint8_t *)"abc"; CFIndex keyDataLength = 3; SecKeyEncoding encoding = kSecKeyEncodingRaw; ok(customKey = SecKeyCreate(kCFAllocatorDefault, descriptor, keyData, keyDataLength, encoding), "create custom key"); is(customKey, initedCustomKey, "CustomKeyInit got the right key"); SecPadding padding = kSecPaddingPKCS1; const uint8_t *src = (const uint8_t *)"defgh"; size_t srcLen = 5; uint8_t dst[5]; size_t dstLen = 5; ok_status(SecKeyDecrypt(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyDecrypt"); ok_status(SecKeyEncrypt(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyEncrypt"); ok_status(SecKeyRawSign(customKey, padding, src, srcLen, dst, &dstLen), "SecKeyRawSign"); ok_status(SecKeyRawVerify(customKey, padding, src, srcLen, dst, dstLen), "SecKeyRawVerify"); is(SecKeyGetSize(customKey, kSecKeyKeySizeInBits), (size_t)5*8, "SecKeyGetSize"); CFDictionaryRef attrDict = NULL; ok(attrDict = SecKeyCopyAttributeDictionary(customKey), "SecKeyCopyAttributeDictionary"); CFReleaseNull(attrDict); CFDataRef pubdata = NULL; ok(SecKeyCopyPublicBytes(customKey, &pubdata) != 0, "SecKeyCopyPublicBytes"); CFReleaseNull(pubdata); CFDataRef wrapped; wrapped = _SecKeyCopyWrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL); ok(wrapped == NULL, "_SecKeyCopyWrapKey"); CFReleaseNull(wrapped); wrapped = _SecKeyCopyUnwrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL); ok(wrapped == NULL, "_SecKeyCopyUnwrapKey"); CFReleaseNull(wrapped); //ok(SecKeyGeneratePair(customKey, ), "SecKeyGeneratePair"); ok(SecKeyGetTypeID() != 0, "SecKeyGetTypeID works"); if (customKey) { CFRelease(customKey); customKey = NULL; } }
static int mySSLPrivKeyRSA_sign(void *key, tls_hash_algorithm hash, const uint8_t *plaintext, size_t plaintextLen, uint8_t *sig, size_t *sigLen) { SecKeyRef keyRef = key; SecKeyAlgorithm algo; switch (hash) { case tls_hash_algorithm_None: return SecKeyRawSign(keyRef, kSecPaddingPKCS1, plaintext, plaintextLen, sig, sigLen); case tls_hash_algorithm_SHA1: algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1; break; case tls_hash_algorithm_SHA256: algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256; break; case tls_hash_algorithm_SHA384: algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384; break; case tls_hash_algorithm_SHA512: algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512; break; default: /* Unsupported hash - Internal error */ return errSSLInternal; } int err = errSSLInternal; CFDataRef signature = NULL; CFDataRef data = NULL; data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, plaintext, plaintextLen, kCFAllocatorNull); require(data, errOut); signature = SecKeyCreateSignature(keyRef, algo, data , NULL); require(signature, errOut); CFIndex len = CFDataGetLength(signature); const uint8_t *p = CFDataGetBytePtr(signature); require(p, errOut); require(len>=*sigLen, errOut); memcpy(sig, p, len); *sigLen = len; err = noErr; errOut: CFReleaseSafe(data); CFReleaseSafe(signature); return err; }
size_t crypt_apple_private_encrypt(void* data, size_t data_size, void* encrypted_data, size_t encrypted_data_size) { SecKeyRef privateKey = _crypt_get_private_key(); size_t len = 0; if (privateKey != NULL) { len = encrypted_data_size; OSStatus err = SecKeyRawSign(privateKey, kSecPaddingNone, data, data_size, encrypted_data, &len); if (err != noErr) len = 0; CFRelease(privateKey); } return len; }
void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen) { SecKeyRef privateKey = NULL; OSStatus status; status = SecIdentityCopyPrivateKey(identity, &privateKey); if (status != noErr) { printErrorStatusMsg("signData: SecIdentityCopyPrivateKey", status); *tlen = 0; return; } status = SecKeyRawSign(privateKey, kSecPaddingPKCS1, from, flen, to, tlen); CFRelease(privateKey); if (status != noErr) { printErrorStatusMsg("signData: SecKeyRawSign", status); *tlen = 0; return; } }
/* * Raw RSA/DSA sign/verify. */ OSStatus sslRawSign( SSLContext *ctx, SSLPrivKey *privKey, const uint8_t *plainText, size_t plainTextLen, uint8_t *sig, // mallocd by caller; RETURNED size_t sigLen, // available size_t *actualBytes) // RETURNED { #if 0 RSAStatus rsaStatus; #if RSA_SIG_SHARE_GIANT RSASignBuffer *signBuffer = (RSASignBuffer *)sig; assert(sigLen >= sizeof(RSASignBuffer)); #endif assert(actualBytes != NULL); /* @@@ Shouldn't need to init giSigLen according to libgRSA docs. */ gi_uint16 giSigLen = sigLen; rsaStatus = RSA_Sign(&privKey->rsaKey, RP_PKCS1, plainText, plainTextLen, #if RSA_SIG_SHARE_GIANT signBuffer, #else sig, #endif &giSigLen); *actualBytes = giSigLen; return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr; #else size_t inOutSigLen = sigLen; assert(actualBytes != NULL); OSStatus status = SecKeyRawSign(SECKEYREF(privKey), kSecPaddingPKCS1, plainText, plainTextLen, sig, &inOutSigLen); if (status) { sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", status); } /* Since the KeyExchange already allocated modulus size bytes we'll use all of them. SecureTransport has always sent that many bytes, so we're not going to deviate, to avoid interoperability issues. */ if (!status && (inOutSigLen < sigLen)) { size_t offset = sigLen - inOutSigLen; memmove(sig + offset, sig, inOutSigLen); memset(sig, 0, offset); inOutSigLen = sigLen; } *actualBytes = inOutSigLen; return status; #endif }
static void testkeygen2(size_t keySizeInBits) { SecKeyRef pubKey = NULL, privKey = NULL; size_t keySizeInBytes = (keySizeInBits + 7) / 8; CFNumberRef kzib; int32_t keysz32 = (int32_t)keySizeInBits; CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault); CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID); CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString); CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString); CFReleaseNull(ourUUID); CFReleaseNull(uuidString); CFStringAppend(publicName, CFSTR("-Public-41")); CFStringAppend(privateName, CFSTR("-Private-41")); CFMutableDictionaryRef pubd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault, kSecAttrLabel, publicName, NULL); CFMutableDictionaryRef privd = CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault, kSecAttrLabel, privateName, NULL); kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32); CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecAttrKeyType, kSecAttrKeyTypeEC, kSecAttrKeySizeInBits, kzib, kSecAttrIsPermanent, kCFBooleanTrue, kSecPublicKeyAttrs, pubd, kSecPrivateKeyAttrs, privd, NULL); CFReleaseNull(kzib); OSStatus status; ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey), "Generate %ld bit (%ld byte) persistent RSA keypair", keySizeInBits, keySizeInBytes); CFReleaseNull(kgp); SKIP: { skip("keygen failed", 8, status == errSecSuccess); ok(pubKey, "pubkey returned"); ok(privKey, "privKey returned"); is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok"); is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok"); SecKeyRef pubKey2, privKey2; CFDictionaryAddValue(pubd, kSecClass, kSecClassKey); CFDictionaryAddValue(pubd, kSecReturnRef, kCFBooleanTrue); CFDictionaryAddValue(privd, kSecClass, kSecClassKey); CFDictionaryAddValue(privd, kSecReturnRef, kCFBooleanTrue); CFDictionaryAddValue(privd, kSecAttrCanSign, kCFBooleanTrue); ok_status(SecItemCopyMatching(pubd, (CFTypeRef *)&pubKey2), "retrieve pub key by label"); ok(pubKey2, "got valid object"); ok_status(SecItemCopyMatching(privd, (CFTypeRef *)&privKey2), "retrieve priv key by label and kSecAttrCanSign"); ok(privKey2, "got valid object"); /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; size_t sigLen = SecKeyGetSize(privKey2, kSecKeySignatureSize); uint8_t sig[sigLen]; ok_status(SecKeyRawSign(privKey2, kSecPaddingPKCS1, something, sizeof(something), sig, &sigLen), "sign something"); ok_status(SecKeyRawVerify(pubKey2, kSecPaddingPKCS1, something, sizeof(something), sig, sigLen), "verify sig on something"); /* Cleanup. */ CFReleaseNull(pubKey2); CFReleaseNull(privKey2); } /* delete from keychain - note: do it before releasing publicName and privateName because pubd and privd have no retain/release callbacks */ ok_status(SecItemDelete(pubd), "delete generated pub key"); ok_status(SecItemDelete(privd), "delete generated priv key"); /* Cleanup. */ CFReleaseNull(pubKey); CFReleaseNull(privKey); CFReleaseNull(publicName); CFReleaseNull(privateName); CFReleaseNull(pubd); CFReleaseNull(privd); }
static void testkeygen(size_t keySizeInBits) { SecKeyRef pubKey = NULL, privKey = NULL; size_t keySizeInBytes = (keySizeInBits + 7) / 8; CFNumberRef kzib; int32_t keysz32 = (int32_t)keySizeInBits; kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32); CFMutableDictionaryRef kgp = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); CFDictionaryAddValue(kgp, kSecAttrKeyType, kSecAttrKeyTypeEC); CFDictionaryAddValue(kgp, kSecAttrKeySizeInBits, kzib); OSStatus status; ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey), "Generate %ld bit (%ld byte) EC keypair", keySizeInBits, keySizeInBytes); CFRelease(kzib); CFRelease(kgp); SKIP: { skip("keygen failed", 8, status == errSecSuccess); ok(pubKey, "pubkey returned"); ok(privKey, "privKey returned"); is(SecKeyGetSize(pubKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "public key size is ok"); is(SecKeyGetSize(privKey, kSecKeyKeySizeInBits), (size_t) keySizeInBits, "private key size is ok"); /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; uint8_t sig[8+2*keySizeInBytes]; size_t sigLen = sizeof(sig); ok_status(SecKeyRawSign(privKey, kSecPaddingNone, something, sizeof(something), sig, &sigLen), "sign something"); ok_status(SecKeyRawVerify(pubKey, kSecPaddingNone, something, sizeof(something), sig, sigLen), "verify sig on something"); testdigestandsign(privKey, pubKey); const void *privkeys[] = { kSecValueRef }; const void *privvalues[] = { privKey }; CFDictionaryRef privitem = CFDictionaryCreate(NULL, privkeys, privvalues, array_size(privkeys), NULL, NULL); ok_status(SecItemAdd(privitem, NULL), "add private key"); ok_status(SecItemDelete(privitem), "delete public key"); CFReleaseNull(privitem); const void *pubkeys[] = { kSecValueRef }; const void *pubvalues[] = { pubKey }; CFDictionaryRef pubitem = CFDictionaryCreate(NULL, pubkeys, pubvalues, array_size(pubkeys), NULL, NULL); ok_status(SecItemAdd(pubitem, NULL), "add public key"); ok_status(SecItemDelete(pubitem), "delete public key"); CFReleaseNull(pubitem); /* Cleanup. */ CFReleaseNull(pubKey); CFReleaseNull(privKey); } }
static void tests(void) { CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _user_one_p12, sizeof(_user_one_p12), kCFAllocatorNull); CFArrayRef items = NULL; SecCertificateRef cert = NULL; SecKeyRef pkey = NULL; is_status(SecPKCS12Import(message, NULL, NULL), errSecAuthFailed, "try null password on a known good p12"); CFStringRef password = CFSTR("user-one"); CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import user one"); is(CFArrayGetCount(items), 1, "one identity"); CFDictionaryRef item = CFArrayGetValueAtIndex(items, 0); SecIdentityRef identity = NULL; ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); CFReleaseNull(pkey); message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _user_two_p12, sizeof(_user_two_p12), kCFAllocatorNull); items = NULL; password = CFSTR("user-two"); options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import user two"); is(CFArrayGetCount(items), 1, "one identity"); item = CFArrayGetValueAtIndex(items, 0); ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); CFReleaseNull(pkey); message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ECDSA_fails_import_p12, ECDSA_fails_import_p12_len, kCFAllocatorNull); items = NULL; password = CFSTR("test"); options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase, (const void **)&password, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ok_status(SecPKCS12Import(message, options, &items), "import ECDSA_fails_import_p12"); is(CFArrayGetCount(items), 1, "one identity"); item = CFArrayGetValueAtIndex(items, 0); ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data"); ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef"); ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key"); ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate"); CFDataRef pubdata = NULL; SecKeyRef pubkey = NULL; ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key"); ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault, CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes), "recreate seckey"); /* Sign something. */ uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, }; size_t sigLen = SecKeyGetSize(pkey, kSecKeySignatureSize); uint8_t sig[sigLen]; ok_status(SecKeyRawSign(pkey, kSecPaddingPKCS1, something, sizeof(something), sig, &sigLen), "sign something"); ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1, something, sizeof(something), sig, sigLen), "verify sig on something"); CFReleaseNull(pubdata); CFReleaseNull(pubkey); CFReleaseNull(pkey); ok(pkey = SecKeyCreateECPrivateKey(kCFAllocatorDefault, ECDSA_fails_import_priv_only, ECDSA_fails_import_priv_only_len, kSecKeyEncodingPkcs1), "import privkey without pub"); ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key"); ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault, CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes), "recreate seckey"); ok_status(SecKeyRawVerify(pubkey, kSecPaddingPKCS1, something, sizeof(something), sig, sigLen), "verify sig on something"); CFReleaseNull(pubdata); CFReleaseNull(pubkey); CFReleaseNull(pkey); CFReleaseNull(items); CFReleaseNull(message); CFReleaseNull(options); CFReleaseNull(password); CFReleaseNull(cert); }