summaryrefslogtreecommitdiffstats
path: root/modules/libmar/verify/MacVerifyCrypto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libmar/verify/MacVerifyCrypto.cpp')
-rw-r--r--modules/libmar/verify/MacVerifyCrypto.cpp218
1 files changed, 218 insertions, 0 deletions
diff --git a/modules/libmar/verify/MacVerifyCrypto.cpp b/modules/libmar/verify/MacVerifyCrypto.cpp
new file mode 100644
index 0000000000..d1d1200fef
--- /dev/null
+++ b/modules/libmar/verify/MacVerifyCrypto.cpp
@@ -0,0 +1,218 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <dlfcn.h>
+
+#include "cryptox.h"
+
+// We declare the necessary parts of the Security Transforms API here since
+// we're building with the 10.6 SDK, which doesn't know about Security
+// Transforms.
+#if defined(__cplusplus)
+extern "C" {
+#endif
+const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
+typedef CFTypeRef SecTransformRef;
+typedef OpaqueSecKeyRef* SecKeyRef;
+
+typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc)(
+ CFReadStreamRef inputStream);
+SecTransformCreateReadTransformWithReadStreamFunc
+ SecTransformCreateReadTransformWithReadStreamPtr = NULL;
+typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform,
+ CFErrorRef* error);
+SecTransformExecuteFunc SecTransformExecutePtr = NULL;
+typedef SecTransformRef (*SecVerifyTransformCreateFunc)(SecKeyRef key,
+ CFDataRef signature,
+ CFErrorRef* error);
+SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr = NULL;
+typedef Boolean (*SecTransformSetAttributeFunc)(SecTransformRef transform,
+ CFStringRef key,
+ CFTypeRef value,
+ CFErrorRef* error);
+SecTransformSetAttributeFunc SecTransformSetAttributePtr = NULL;
+#if defined(__cplusplus)
+}
+#endif
+
+CryptoX_Result CryptoMac_InitCryptoProvider() {
+ if (!SecTransformCreateReadTransformWithReadStreamPtr) {
+ SecTransformCreateReadTransformWithReadStreamPtr =
+ (SecTransformCreateReadTransformWithReadStreamFunc)dlsym(
+ RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream");
+ }
+ if (!SecTransformExecutePtr) {
+ SecTransformExecutePtr =
+ (SecTransformExecuteFunc)dlsym(RTLD_DEFAULT, "SecTransformExecute");
+ }
+ if (!SecVerifyTransformCreatePtr) {
+ SecVerifyTransformCreatePtr = (SecVerifyTransformCreateFunc)dlsym(
+ RTLD_DEFAULT, "SecVerifyTransformCreate");
+ }
+ if (!SecTransformSetAttributePtr) {
+ SecTransformSetAttributePtr = (SecTransformSetAttributeFunc)dlsym(
+ RTLD_DEFAULT, "SecTransformSetAttribute");
+ }
+ if (!SecTransformCreateReadTransformWithReadStreamPtr ||
+ !SecTransformExecutePtr || !SecVerifyTransformCreatePtr ||
+ !SecTransformSetAttributePtr) {
+ return CryptoX_Error;
+ }
+ return CryptoX_Success;
+}
+
+CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData) {
+ if (!aInputData) {
+ return CryptoX_Error;
+ }
+
+ void* inputData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+ if (!inputData) {
+ return CryptoX_Error;
+ }
+
+ *aInputData = inputData;
+ return CryptoX_Success;
+}
+
+CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData,
+ void* aBuf, unsigned int aLen) {
+ if (aLen == 0) {
+ return CryptoX_Success;
+ }
+ if (!aInputData || !*aInputData) {
+ return CryptoX_Error;
+ }
+
+ CFMutableDataRef inputData = (CFMutableDataRef)*aInputData;
+
+ CFDataAppendBytes(inputData, (const uint8*)aBuf, aLen);
+ return CryptoX_Success;
+}
+
+CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData,
+ unsigned int aDataSize,
+ CryptoX_PublicKey* aPublicKey) {
+ if (!aCertData || aDataSize == 0 || !aPublicKey) {
+ return CryptoX_Error;
+ }
+ *aPublicKey = NULL;
+ CFDataRef certData = CFDataCreate(kCFAllocatorDefault, aCertData, aDataSize);
+ if (!certData) {
+ return CryptoX_Error;
+ }
+
+ SecCertificateRef cert =
+ SecCertificateCreateWithData(kCFAllocatorDefault, certData);
+ CFRelease(certData);
+ if (!cert) {
+ return CryptoX_Error;
+ }
+
+ OSStatus status = SecCertificateCopyPublicKey(cert, (SecKeyRef*)aPublicKey);
+ CFRelease(cert);
+ if (status != 0) {
+ return CryptoX_Error;
+ }
+
+ return CryptoX_Success;
+}
+
+CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
+ CryptoX_PublicKey* aPublicKey,
+ const unsigned char* aSignature,
+ unsigned int aSignatureLen) {
+ if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey ||
+ !aSignature || aSignatureLen == 0) {
+ return CryptoX_Error;
+ }
+
+ CFDataRef signatureData =
+ CFDataCreate(kCFAllocatorDefault, aSignature, aSignatureLen);
+ if (!signatureData) {
+ return CryptoX_Error;
+ }
+
+ CFErrorRef error;
+ SecTransformRef verifier = SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
+ signatureData, &error);
+ if (!verifier || error) {
+ if (error) {
+ CFRelease(error);
+ }
+ CFRelease(signatureData);
+ return CryptoX_Error;
+ }
+
+ SecTransformSetAttributePtr(verifier, kSecDigestTypeAttribute, kSecDigestSHA2,
+ &error);
+ if (error) {
+ CFRelease(error);
+ CFRelease(signatureData);
+ CFRelease(verifier);
+ return CryptoX_Error;
+ }
+
+ int digestLength = 384;
+ CFNumberRef dLen =
+ CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestLength);
+ SecTransformSetAttributePtr(verifier, kSecDigestLengthAttribute, dLen,
+ &error);
+ CFRelease(dLen);
+ if (error) {
+ CFRelease(error);
+ CFRelease(signatureData);
+ CFRelease(verifier);
+ return CryptoX_Error;
+ }
+
+ SecTransformSetAttributePtr(verifier, kSecTransformInputAttributeName,
+ (CFDataRef)*aInputData, &error);
+ if (error) {
+ CFRelease(error);
+ CFRelease(signatureData);
+ CFRelease(verifier);
+ return CryptoX_Error;
+ }
+
+ CryptoX_Result result = CryptoX_Error;
+ CFTypeRef rv = SecTransformExecutePtr(verifier, &error);
+ if (error) {
+ CFRelease(error);
+ CFRelease(signatureData);
+ CFRelease(verifier);
+ return CryptoX_Error;
+ }
+
+ if (CFGetTypeID(rv) == CFBooleanGetTypeID() &&
+ CFBooleanGetValue((CFBooleanRef)rv) == true) {
+ result = CryptoX_Success;
+ }
+
+ CFRelease(signatureData);
+ CFRelease(verifier);
+
+ return result;
+}
+
+void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData) {
+ if (!aInputData || !*aInputData) {
+ return;
+ }
+
+ CFMutableDataRef inputData = NULL;
+ inputData = (CFMutableDataRef)*aInputData;
+
+ CFRelease(inputData);
+}
+
+void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey) {
+ if (!aPublicKey || !*aPublicKey) {
+ return;
+ }
+
+ CFRelease((SecKeyRef)*aPublicKey);
+}