Hi
I want to create secIdentity from certificate & key.
I receive certificate from my server and I have private key of that.
My certificate is like this -----BEGIN CERTIFICATE-----\nMIIEyTC...jix0=\n-----END CERTIFICATE-----
And private key is like this -----BEGIN RSA PRIVATE KEY-----\nMIIEp...5KM=\n-----END RSA PRIVATE KEY-----\n
I am trying to create secIdentity by saving certificate and key in keychain, but I am getting -25300
as error.
To create the identity my code is like this.
func deleteCertificateAndKey(certLabel:String, keyTag:Data) -> Bool {
// Query for the certificate
let query: [String: Any] = [kSecClass as String: kSecClassCertificate,
kSecAttrLabel as String: certLabel]
// Attempt to delete the certificate
let certificateDeleteStatus = SecItemDelete(query as CFDictionary)
print("certificateDeleteStatus: \(certificateDeleteStatus)")
// if certificateDeleteStatus == errSecSuccess {
// print("Certificate Certificate deleted successfully.")
// } else {
// print("Failed to delete certificate Certificate. Error: \(certificateDeleteStatus)")
// return false
// }
//
// Query for the private key associated with the certificate
let keyQuery: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrApplicationTag as String: keyTag
]
// Attempt to delete the private key
let keyDeleteStatus = SecItemDelete(keyQuery as CFDictionary)
print("keyDeleteStatus: \(keyDeleteStatus)")
// if keyDeleteStatus == errSecSuccess {
// print("Private key associated with Key deleted successfully.")
// return true
// } else {
// print("Failed to delete private key for Key. Error: \(keyDeleteStatus)")
// return false
// }
return true;
}
func stripPemHeaders(_ pemString: String) -> String {
var result = pemString
//
result = result.replacingOccurrences(of: "-----BEGIN RSA PRIVATE KEY-----\n", with: "")
result = result.replacingOccurrences(of: "\n-----END RSA PRIVATE KEY-----\n", with: "")
//
result = result.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----\n", with: "")
result = result.replacingOccurrences(of: "\n-----END CERTIFICATE-----", with: "")
return result
}
func loadIdentity(certificate: String, privateKey: String)-> SecIdentity? {
let strippedCertificate = stripPemHeaders(certificate)
print("strippedCertificate : \(strippedCertificate)")
guard let certData = Data(base64Encoded: strippedCertificate, options:NSData.Base64DecodingOptions.ignoreUnknownCharacters) else {
print("Unable to decode certificate PEM")
return nil
}
print("certData: \(certData)")
// Create certificate object
guard let cert = SecCertificateCreateWithData(kCFAllocatorDefault, certData as CFData) else {
print("Unable to create certificate")
return nil
}
let addCertQuery: [String: Any] = [kSecClass as String: kSecClassCertificate,
kSecValueRef as String: cert,
kSecAttrLabel as String: "shahanshahAlam"]
let tag = "fedvfdvjjkdf-tag".data(using: .utf8)!
_ = deleteCertificateAndKey(certLabel: "shahanshahAlam",keyTag: tag )
// print("deleteStatus finished with status: \(deleteStatus)")
let certAddStatus = SecItemAdd(addCertQuery as CFDictionary, nil)
print("certAddStatus finished with status: \(certAddStatus)")
let strippedPrivateKey = stripPemHeaders(privateKey)
print("strippedPrivateKey : \(strippedPrivateKey)")
guard let pemKeyData = Data(base64Encoded: strippedPrivateKey, options:NSData.Base64DecodingOptions.ignoreUnknownCharacters) else {
print("Error: couldn't parse the privateKeyString, pls check if headers were removed: \(privateKey)")
return nil
}
print("pemKeyData finished with status: \(pemKeyData)")
let sizeInBits = pemKeyData.count * 8
let keyDict: [CFString: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits: NSNumber(value: sizeInBits),
kSecReturnPersistentRef: true
]
var error: Unmanaged<CFError>?
guard let key = SecKeyCreateWithData(pemKeyData as CFData, keyDict as CFDictionary, &error) else {
print("Failed creating a Certificate from data \(error.debugDescription)")
return nil
}
let addKeyQuery: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrIsPermanent as String: true,
kSecValueRef as String: key,
kSecAttrApplicationTag as String: tag
]
let privKeyAddStatus = SecItemAdd(addKeyQuery as CFDictionary, nil)
print("privKeyAddStatus status finished with status: \(privKeyAddStatus)")
// query for all avaiable identities
let getIdentityQuery = [
kSecClass : kSecClassIdentity,
// kSecReturnData : true,
// kSecReturnAttributes : true,
kSecReturnRef : true,
kSecAttrApplicationTag as String: tag,
kSecMatchLimit : kSecMatchLimitAll
] as CFDictionary
var identityItem: CFTypeRef?
let status = SecItemCopyMatching(getIdentityQuery , &identityItem)
print("identityItem finished with status: \(String(describing: identityItem))")
print("status finished with status: \(status)")
guard status == errSecSuccess else {
print("Unable to create identity")
return nil
}
return (identityItem as! SecIdentity);
}
How can I fix that.