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(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({ CFStringRef.fromRef(security.kSecClass): CFStringRef.fromRef(security.kSecClassIdentity), CFStringRef.fromRef(security.kSecReturnRef): CFBooleanRef.fromBool(True), CFStringRef.fromRef(security.kSecReturnAttributes): CFBooleanRef.fromBool(True), CFStringRef.fromRef(security.kSecMatchLimit): CFStringRef.fromRef(security.kSecMatchLimitAll), }) result = ffi.new("CFTypeRef *") err = security.SecItemCopyMatching(match.ref(), result) if err != 0: return None result = CFArrayRef(result[0]) for item in result.toList(): if item[str(CFStringRef.fromRef(security.kSecAttrLabel))] == identity: secidentity = item[str(CFStringRef.fromRef(security.kSecValueRef))] break else: raise Error("Could not find Keychain identity: {}".format(identity)) return secidentity
def get_subject(self): """ Use Security.framework to extract the componentized SubjectName field and map OID values to strings and store in an L{X509Name} object. """ keys = CFArrayRef.fromList( [CFStringRef.fromRef(security.kSecOIDX509V1SubjectName)]) error = ffi.new("CFErrorRef *") values = security.SecCertificateCopyValues(self._x509.ref(), keys.ref(), error) if values == ffi.NULL: error = CFErrorRef(error[0]) raise Error("Unable to get certificate subject") values = CFDictionaryRef(values).toDict() value = values[str( CFStringRef.fromRef(security.kSecOIDX509V1SubjectName))] components = {} if value[str(CFStringRef.fromRef( security.kSecPropertyKeyType))] == str( CFStringRef.fromRef(security.kSecPropertyTypeSection)): for item in value[str( CFStringRef.fromRef(security.kSecPropertyKeyValue))]: if item[str(CFStringRef.fromRef( security.kSecPropertyKeyType))] == str( CFStringRef.fromRef( security.kSecPropertyTypeString)): v = item[str( CFStringRef.fromRef(security.kSecPropertyKeyValue))] k = OID2STR.get( item[str( CFStringRef.fromRef( security.kSecPropertyKeyLabel))], "Unknown") components[k] = v return X509Name("Subject Name", components)
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## """ An API compatible replace for pyOpenSSL's OpenSSL.crypto module that uses Security.frameowork. """ from osx._corefoundation import ffi, lib as security from osx.corefoundation import CFDictionaryRef, CFStringRef, CFArrayRef, \ CFBooleanRef, CFObjectRef, CFErrorRef, CFDataRef userIDOID = "0.9.2342.19200300.100.1.1" OID2STR = { str(CFStringRef.fromRef(security.kSecOIDCommonName)): "CN", str(CFStringRef.fromRef(security.kSecOIDCountryName)): "C", str(CFStringRef.fromRef(security.kSecOIDEmailAddress)): "emailAddress", str(CFStringRef.fromRef(security.kSecOIDLocalityName)): "L", str(CFStringRef.fromRef(security.kSecOIDOrganizationName)): "O", str(CFStringRef.fromRef(security.kSecOIDOrganizationalUnitName)): "OU", str(CFStringRef.fromRef(security.kSecOIDStateProvinceName)): "ST", userIDOID: "UID", } FILETYPE_PEM = 1 FILETYPE_ASN1 = 2 FILETYPE_DEFAULT = 3 TYPE_RSA = 6 TYPE_DSA = 116