Reputation: 769
I'm trying to add a certificate to the keychain. I saw several posts that make this from a file, but I want to create one from a NSString.
My NSString is on RSA - 64base and is like:
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIJAL8qgXMVVVhPMA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNVBAYTAkJSMRIw
...
FT70at8bty9ocDaXuI3j6mfw2SI=
-----END CERTIFICATE-----
And I'm trying to do something like this:
+ (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {
NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
[searchDictionary setObject:(__bridge id)kSecClassCertificate forKey:(__bridge id)kSecClass];
NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrGeneric];
[searchDictionary setObject:encodedIdentifier forKey:(__bridge id)kSecAttrAccount];
[searchDictionary setObject:SERVICE_NAME forKey:(__bridge id)kSecAttrService];
return searchDictionary;
}
+ (BOOL)createKeychainValue:(NSString *)certificado forIdentifier:(NSString *)identifier {
NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
NSData *certificadoData = [certificado dataUsingEncoding:NSUTF8StringEncoding];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certificadoData);
[dictionary setObject:(__bridge id)(cert) forKey:(__bridge id<NSCopying>)(kSecValueRef)];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL);
CFRelease(cert);
if (status == errSecSuccess) {
return YES;
}
return NO;
}
But is getting back the cert as nil. Probably because my certificate is PEM and I need a DER. How can I convert? I'm using openssl on my project.
Upvotes: 4
Views: 987
Reputation: 769
The function that works for me and created the SecCertificateRef was:
+ (NSData *)derFromPem:(NSString *)pem {
BIO *certBio = BIO_new(BIO_s_mem());
BIO_write(certBio, [pem UTF8String], strlen([pem UTF8String]));
X509 *x = PEM_read_bio_X509(certBio,NULL,0,NULL);
BIO *outBio = BIO_new(BIO_s_mem());
i2d_X509_bio(outBio, x);
int len = BIO_pending(outBio);
char *out = calloc(len + 1, 1);
int i = BIO_read(outBio, out, len);
return [NSData dataWithBytes:out length:i];
}
Upvotes: 3
Reputation: 670
Convert RSA public key from PEM to DER:
UPDATE
- (NSData *)derFromPem:(NSString *)pem
{
if (pem.length == 0) {
return nil;
}
NSData *result = nil;
const char *pem_str = [pem UTF8String];
BIO *bio;
RSA *rsa;
// X509 *x509;
bio = BIO_new_mem_buf(pem_str, strlen(pem_str));
if (bio) {
rsa = PEM_read_bio_RSAPublicKey(bio, &rsa, NULL, NULL);
// x509 = PEM_read_bio_X509(bio, &x509, NULL/*password*/, NULL);
if (rsa) { // or if (x509)
uint8_t *buf, *bufp;
int len = i2d_RSAPublicKey(rsa, NULL);
// int len = i2d_X509(x509, NULL);
if (len >= 0) {
buf = bufp = malloc(len);
i2d_RSAPublicKey(rsa, &bufp);
// i2d_X509(x509, &bufp);
}
if (len >= 0) {
result = [NSData dataWithBytes:buf length:len];
free(buf);
}
RSA_free(rsa);
// X509_free(x509);
}
BIO_free(bio);
}
return result;
}
Upvotes: 1