[CalendarServer-changes] [15225] PySecureTransport/trunk/OpenSSL/crypto.py
source_changes at macosforge.org
source_changes at macosforge.org
Sat Oct 24 09:00:51 PDT 2015
Revision: 15225
http://trac.calendarserver.org//changeset/15225
Author: cdaboo at apple.com
Date: 2015-10-24 09:00:50 -0700 (Sat, 24 Oct 2015)
Log Message:
-----------
Add API to check ability of Keychain identity to sign data (checks whether access to private key is allowed).
Modified Paths:
--------------
PySecureTransport/trunk/OpenSSL/crypto.py
Modified: PySecureTransport/trunk/OpenSSL/crypto.py
===================================================================
--- PySecureTransport/trunk/OpenSSL/crypto.py 2015-10-24 15:59:10 UTC (rev 15224)
+++ PySecureTransport/trunk/OpenSSL/crypto.py 2015-10-24 16:00:50 UTC (rev 15225)
@@ -317,22 +317,74 @@
-def load_keychain_identity(subject):
+def check_keychain_identity(identity):
"""
- Retrieve a SecIdentityRef from the KeyChain with a subject that exactly matches the passed in value.
+ Verify that the Keychain identity exists and that the private key is accessible.
- @param subject: subject value to match
- @type subject: L{str}
+ @param identity: identity value to match
+ @type identity: L{str}
+ @return: empty L{str} if OK, error message if not
+ @rtype: L{str}
+ """
+
+ # Always turn off user interaction
+ security.SecKeychainSetUserInteractionAllowed(False)
+
+ try:
+ secidentity = load_keychain_identity(identity)
+ except Error:
+ return "Unable to load Keychain identity: {}".format(identity)
+ pkey = ffi.new("SecKeyRef *")
+ err = security.SecIdentityCopyPrivateKey(secidentity.ref(), pkey)
+ if err != 0:
+ return "Unable to load private key for Keychain identity: {}".format(identity)
+ pkey = CFObjectRef(pkey[0])
+
+ # Try to sign some data with the pkey to check we have access
+ error = ffi.new("CFErrorRef *")
+ signer = security.SecSignTransformCreate(pkey.ref(), error)
+ if error[0] != ffi.NULL:
+ cferror = CFErrorRef(error[0])
+ return "Unable to use private key for Keychain identity: {} - {}".format(identity, cferror.description())
+ signer = CFObjectRef(signer)
+
+ signMe = CFDataRef.fromString("sign me")
+ security.SecTransformSetAttribute(
+ signer.ref(),
+ security.kSecTransformInputAttributeName,
+ signMe.ref(),
+ error
+ )
+ if error[0] != ffi.NULL:
+ cferror = CFErrorRef(error[0])
+ return "Unable to use private key for Keychain identity: {} - {}".format(identity, cferror.description())
+
+ signature = security.SecTransformExecute(signer.ref(), error)
+ if error[0] != ffi.NULL or signature == ffi.NULL:
+ cferror = CFErrorRef(error[0])
+ return "Unable to use private key for Keychain identity: {} - {}".format(identity, cferror.description())
+
+ return ""
+
+
+
+def load_keychain_identity(identity):
+ """
+ Retrieve a SecIdentityRef from the KeyChain with a identity that exactly matches the passed in value.
+
+ @param identity: identity value to match
+ @type identity: L{str}
+
@return: matched SecIdentityRef item or L{None}
@rtype: L{CFObjectRef}
"""
# First try to load this from an identity preference
- cfsubject = CFStringRef.fromString(subject)
- identity = security.SecIdentityCopyPreferred(cfsubject.ref(), ffi.NULL, ffi.NULL)
- if identity != ffi.NULL:
- return CFObjectRef(identity)
+ cfsubject = CFStringRef.fromString(identity)
+ secidentity = security.SecIdentityCopyPreferred(cfsubject.ref(), ffi.NULL, ffi.NULL)
+ if secidentity != ffi.NULL:
+ return CFObjectRef(secidentity)
# Now iterate items to find a match
match = CFDictionaryRef.fromDict({
@@ -351,10 +403,10 @@
result = CFArrayRef(result[0])
for item in result.toList():
- if item[str(CFStringRef.fromRef(security.kSecAttrLabel))] == subject:
- identity = item[str(CFStringRef.fromRef(security.kSecValueRef))]
+ if item[str(CFStringRef.fromRef(security.kSecAttrLabel))] == identity:
+ secidentity = item[str(CFStringRef.fromRef(security.kSecValueRef))]
break
else:
- raise Error("Certificate with id '{}' was not found in the KeyChain".format(subject))
+ raise Error("Could not find Keychain identity: {}".format(identity))
- return identity
+ return secidentity
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20151024/d0309e6c/attachment.html>
More information about the calendarserver-changes
mailing list