Sempre EXC_BAD_ACCESS no SecTrustEvaluate
estou usandoCódigo de exemplo da Apple para avaliar um certificado X509. Eu modifiquei um pouco para obter um certificado do meu pacote (apenas alterei o nome do arquivo).
Quando eu corro isso, ele sempre cai na linha comcomment 5
status = SecTrustEvaluate(myTrust, &trustResult);
. Eu recebo sempreEXC_BAD_ACCESS
lá.
- (BOOL)validateCertificate
{
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"user_signed_cert" ofType:@"crt"];
NSData *certData = [[NSData alloc]
initWithContentsOfFile:thePath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
SecCertificateRef certArray[1] = { myCert };
CFArrayRef myCerts = CFArrayCreate(
NULL, (void *)certArray,
1, NULL);
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
myCerts,
myPolicy,
&myTrust); //4
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
//6 if (trustResult == kSecTrustResultRecoverableTrustFailure) {
}
if (myPolicy)
CFRelease(myPolicy);
}
Alguém sabe o que está errado aqui?
Desde já, obrigado!
Atualização # 1: eu mudei para o seguinte, mas nada muda. O mesmo EXC_BAD_ACCESS emSecTrustEvaluate()
.
NSMutableArray *temp = [[NSMutableArray alloc] init];
[temp addObject:certData];
OSStatus status = SecTrustCreateWithCertificates((__bridge CFArrayRef)temp, myPolicy, &myTrust);
Parece questatus
está vazio depoisSecTrustCreateWithCertificates()
mas não contém um erro.
Qualquer outra sugestão, o que está errado?
Atualização 2: Eu tentei a solução mencionada abaixo e recebi semprekSecTrustResultInvalid
. Eu alterei apenas a criação do certificado de CA para armazenar a chave privadaca.key
porque ao assinar o pedido (client.csr
) Eu recebi a seguinte mensagem de erro:
Signature ok
subject=/CN=foo-by-ZeeCA
Getting CA Private Key
unable to load CA Private Key
Além disso, tive que alterar o comando de solicitação de assinatura paraopenssl x509 -CA ca.pem -in client.csr -CAkey ca.key -req -set_serial 1 -out client.pem
. (adicionado-CAkey ca.key
)
Então usei o código na solução abaixo e adicionei meus caminhos do pacote. Além disso, eu adicionei um caso de switch para o status.
/*
# CA
openssl req -x509 -new -subj /CN=ZeeCA -keyout ca.key -nodes -set_serial 1 > ca.pem
openssl x509 -outform DER -out ca.der -in ca.pem
# create andsign client
openssl req -new -subj /CN=foo-by-ZeeCA -CAkey ca.key -keyout client.key -nodes > client.csr
openssl x509 -CA ca.pem -in client.csr -req -set_serial 1 -out client.pem
# format for client identity import
openssl pkcs12 -export -out client.12 -inkey client.key -in client.pem -CAfile ca.pem -password pass:1234
# format for trust.
openssl x509 -in client.pem -out client.der -outform der
*/
NSString *clientPath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"der"];
//NSString *thePath = @"XXXX/client.der";
NSData *certData = [[NSData alloc]
initWithContentsOfFile:clientPath];
CFDataRef myCertData = (__bridge_retained CFDataRef)certData; //1
assert(myCertData);
SecCertificateRef myCert;
myCert = SecCertificateCreateWithData(NULL, myCertData); //2
assert(myCert);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); //3
NSArray * certArray = [NSArray arrayWithObject:(__bridge id)(myCert)];
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(
(__bridge CFArrayRef)certArray,
myPolicy,
&myTrust); //4
NSString *caPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
NSData *caData = [[NSData alloc]
initWithContentsOfFile:caPath];
CFDataRef myCaData = (__bridge_retained CFDataRef)caData;
SecCertificateRef myCA = SecCertificateCreateWithData(NULL, myCaData);
assert(myCA);
NSArray * myCAs = [NSArray arrayWithObject:(__bridge id)(myCA)];
SecTrustResultType xxx = SecTrustSetAnchorCertificates(myTrust, (__bridge CFArrayRef)(myCAs));
if (xxx != noErr) {
NSLog(@"SecTrustSetAnchorCertificates failed: %d", xxx);
}
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
NSLog(@"Status: %d", status);
}
if (myPolicy)
CFRelease(myPolicy);
if (status == noErr) {
status = SecTrustEvaluate(myTrust, &trustResult); //5 }
switch (status) {
case kSecTrustResultProceed: // 1
NSLog(@"Proceed");
break;
case kSecTrustResultConfirm: // 2
NSLog(@"Confirm");
break;
case kSecTrustResultUnspecified: // 4
NSLog(@"Unspecified");
break;
case kSecTrustResultRecoverableTrustFailure: // 5
NSLog(@"TrustFailure");
break;
case kSecTrustResultDeny: // 3
NSLog(@"Deny");
break;
case kSecTrustResultFatalTrustFailure: // 6
NSLog(@"FatalTrustFailure");
break;
case kSecTrustResultOtherError: // 7
NSLog(@"OtherError");
break;
case kSecTrustResultInvalid: // 0
NSLog(@"Invalid");
break;
default:
NSLog(@"Default");
break;
}
}