He revisado la documentación del marco de seguridad pero parece que no puedo encontrar la forma de obtener todos los certificados en un llavero dado. ¿Hay métodos para lograr esto?Obtener certificados en llavero
Respuesta
Después de la minería de la documentación, archivos de cabecera y los archivos de origen, se me ha ocurrido con el siguiente código:
#import <Security/Security.h>
- (void)logMessageForStatus:(OSStatus)status
functionName:(NSString *)functionName
{
CFStringRef errorMessage;
errorMessage = SecCopyErrorMessageString(status, NULL);
NSLog(@"error after %@: %@", functionName, (NSString *)errorMessage);
CFRelease(errorMessage);
}
- (void)listCertificates
{
OSStatus status;
SecKeychainSearchRef search = NULL;
// The first argument being NULL indicates the user's current keychain list
status = SecKeychainSearchCreateFromAttributes(NULL,
kSecCertificateItemClass, NULL, &search);
if (status != errSecSuccess) {
[self logMessageForStatus:status
functionName:@"SecKeychainSearchCreateFromAttributes()"];
return;
}
SecKeychainItemRef searchItem = NULL;
while (SecKeychainSearchCopyNext(search, &searchItem) != errSecItemNotFound) {
SecKeychainAttributeList attrList;
CSSM_DATA certData;
attrList.count = 0;
attrList.attr = NULL;
status = SecKeychainItemCopyContent(searchItem, NULL, &attrList,
(UInt32 *)(&certData.Length),
(void **)(&certData.Data));
if (status != errSecSuccess) {
[self logMessageForStatus:status
functionName:@"SecKeychainItemCopyContent()"];
CFRelease(searchItem);
continue;
}
// At this point you should have a valid CSSM_DATA structure
// representing the certificate
SecCertificateRef certificate;
status = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3,
CSSM_CERT_ENCODING_BER, &certificate);
if (status != errSecSuccess) {
[self logMessageForStatus:status
functionName:@"SecCertificateCreateFromData()"];
SecKeychainItemFreeContent(&attrList, certData.Data);
CFRelease(searchItem);
continue;
}
// Do whatever you want to do with the certificate
// For instance, print its common name (if there's one)
CFStringRef commonName = NULL;
SecCertificateCopyCommonName(certificate, &commonName);
NSLog(@"common name = %@", (NSString *)commonName);
if (commonName) CFRelease(commonName);
SecKeychainItemFreeContent(&attrList, certData.Data);
CFRelease(searchItem);
}
CFRelease(search);
}
Si se dirige a Mac OS 10.6 o posterior, puede utilizar SecItemCopyMatching
para consultar fácilmente la llavero:
SecKeychainRef keychain = ...
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
kSecClassCertificate, kSecClass,
[NSArray arrayWithObject:(id)keychain], kSecMatchSearchList,
kCFBooleanTrue, kSecReturnRef,
kSecMatchLimitAll, kSecMatchLimit,
nil];
NSArray *items = nil;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&items);
if (status) {
if (status != errSecItemNotFound)
LKKCReportError(status, @"Can't search keychain");
return nil;
}
return [items autorelease]; // items contains all SecCertificateRefs in keychain
Tenga en cuenta que no debe utilizar este para implementar la validación de certificados - la presencia de un certificado de CA en un llavero no indica que es de confianza para firmar certificados para cualquier política en particular. Consulte la Guía de programación de certificado, clave y confianza de para obtener información acerca de cómo realizar la validación de certificados con el llavero.
Esta es una gran respuesta, ya que 'SecKeychainSearchCreateFromAttributes' y' SecKeychainSearchCopyNext' están en desuso a partir de 10.7. Esto requiere algunas versiones locas para trabajar con ARC, pero usar un 'CFMutableDictionaryRef' y configurar estas teclas funciona igual de bien. ¡Gracias! –
- 1. Cómo obtener atributos de elementos de llavero
- 2. Cómo hacer que se vea libcurl en el Mac Llavero para certificados
- 3. Tienda NSDiccionario en llavero
- 4. Obtener una lista de certificados del almacén de certificados en C#
- 5. Desbloquear llavero OSX sin contraseña?
- 6. Cómo guardar CFUUID en llavero
- 7. Llavero tipo iPhone en Android?
- 8. Xcode no pudo encontrar un par de certificados de clave privada válido para este perfil en su llavero
- 9. ¿Varios certificados/perfiles de aprovisionamiento en un organizador Xcode?
- 10. Aceptar certificados en Java
- 11. Certificados: ¿cuándo se instalan en el almacén de certificados?
- 12. Cómo obtener los certificados de Amazon MySQL RDS
- 13. iOS guarde varias contraseñas en el llavero
- 14. ¿Puedo acceder al llavero en el iPhone?
- 15. ¿Funciona realmente el llavero en iOS?
- 16. ¿Cómo puedo obtener LWP para validar certificados de servidor SSL?
- 17. Solicitudes SOAP en Ruby con certificados X509
- 18. certificados X.509 en WCF?
- 19. Certificados de SmartCard en C#
- 20. Certificados de cliente encadenados
- 21. Subversión en Mac - se niega a obtener la contraseña del llavero
- 22. ¿Cómo leer certificados de mi tienda de certificados?
- 23. Enumerar todos los elementos de Llavero en mi aplicación iOS
- 24. iphone - certificado de distribución que no se muestra en el acceso al llavero
- 25. OCR un llavero RSA (token de seguridad)
- 26. Mac OS X Acceso a llavero: "No se pudo encontrar un llavero predeterminado" error
- 27. WCF, Seguridad y Certificados
- 28. certificados SSL CNAME
- 29. iPhone TrustStore CA certificados
- 30. No se puede instalar un certificado de desarrollador de iPhone en el llavero
Absolutamente brillante. Muchas gracias! –
@Dylan Cheers. Considere archivar un radar de solicitud de mejora (o tres, en realidad) con Apple: este podría ser un código de muestra, esto podría estar en la Guía de programación de seguridad, y podrían proporcionar una API más simple basada en Cocoa para esto. –
El 'searchItem' devuelto por' SecKeychainSearchCopyNext' ya es un 'SecCertificateRef'. (Está buscando elementos en la clase de certificado, por lo que cada resultado es un elemento de certificado.) No es necesario extraer y reinterpretar sus datos: un simple encasillado obtendrá mejores resultados. –