2012-07-20 1 views
2

인증서 파일을 이메일로 보내고 장치에 설치하기 만하면 자체 서명 된 X509 인증서를 iPhone으로 가져 왔습니다. 이제 위의 인증서를 사용하여 서명해야하는 내 IOS 응용 프로그램의 특정 인증서를 확인하고 싶습니다. 기본적으로 가져온 인증서는 CA의 루트 인증서로 사용됩니다.iOS 자체 서명 CA 인증서 및 자체 생성 인증서

가져온 인증서가 키 체인에 저장됩니까?

가져온 인증서를 기반으로 다른 인증서의 프로그래밍 방식으로 유효성을 검사하려면 어떻게해야합니까? (두 번째 인증서는 이전에 가져온 CA 인증서로 서명 한 경우에만 유효합니다.)

누구나 이러한 시나리오에 경험이 있습니까?

미리 감사드립니다.

답변

3

1) 예 - 키 체인에 있습니다.

2) 모든 인증서 또는 사용자 본인에 대한 신뢰도 SecTrustCreateWithCertificates(), SecTrustEvaluate()을 사용하여 2) 확인합니다.

3) 폭이 넓은 인증서에 대해 확인한 경우 키 체인에서 자신의 인증서를 선택적으로 조회 할 수 있습니다. DER을 얻으십시오; SHA1을 계산하고 코드에서 하드 코드 된 SHA1과 비교하십시오.

코드는 아래와 같습니다.

NSMutableArray *serverChain = -- array with what you want to check 
NSMutableArray *trustedCertRefs = <your-hardcoded-certs>; 

SecTrustRef noHostTrustRef = NULL; 
OSErr status = SecTrustCreateWithCertificates((__bridge CFArrayRef)serverChain, 
           SecPolicyCreateSSL(NO, nil), &noHostTrustRef); 

if (status != noErr) { 
    NSLog(@"SecTrustCreateWithCertificates failed: %hd", status); 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
} 


status = SecTrustSetAnchorCertificates(noHostTrustRef, 
         (__bridge CFArrayRef)trustedCertRefs); 
if (status != noErr) { 
    NSLog(@"SecTrustSetAnchorCertificates failed: %hd", status); 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
} 

status = SecTrustEvaluate(noHostTrustRef, &result); 
if (status != noErr) { 
    NSLog(@"SecTrustEvaluate failed: %hd", status); 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
} 
CFRelease(noHostTrustRef); 

/* From SecTrust.h: 
* 
* SecTrustResultType results have two dimensions. They specify both whether 
* evaluation suceeded and whether this is because of a user decision. 
* 
* In practice the commonly expected result is kSecTrustResultUnspecified, 
* which indicates a positive result that wasn't decided by the user. 
* 
* The common failure is kSecTrustResultRecoverableTrustFailure, which means a 
* negative result. kSecTrustResultProceed and kSecTrustResultDeny are the 
* positive and negative result respectively when decided by the user. User 
* decisions are persisted through the use of SecTrustCopyExceptions() and 
* SecTrustSetExceptions(). Finally kSecTrustResultFatalTrustFailure is a 
* negative result that should not be circumvented. In fact only in the case 
* of kSecTrustResultRecoverableTrustFailure should a user ever be asked. 
*/ 
switch (result) { 
    case kSecTrustResultProceed: // 1 
    case kSecTrustResultConfirm: // 2 
    case kSecTrustResultUnspecified: // 4 
     return YES 
     break; 
    case kSecTrustResultRecoverableTrustFailure: // 5 
    case kSecTrustResultDeny: // 3 
    case kSecTrustResultFatalTrustFailure: // 6 
    case kSecTrustResultOtherError: // 7 
    case kSecTrustResultInvalid: // 0 
    default: 
     return NO: 
     break; 
} 
[[challenge sender] cancelAuthenticationChallenge:challenge]; 

또는 당신이 신뢰 체인을받을 경우, 이미 (당신의 인증서 표시에 따라서 및) 키 체인에 대해 검증 네트워크 스택에서 말 - 다음은 인증서 표시를 추출 할 수 있습니다; 그 (것)들에 SecCertificateCopyData()를하십시오; SHA1 그 NSData 귀하의 하드 코드 된 SHA1에 비해 정확히 그걸 확인되었는지 확인하십시오.

+0

감사합니다. 정확히 내가 무엇을 찾고 있었는지. 그런데 키 체인에서 전체 인증서를 가져 오거나 추출하는 것도 가능합니까? 예를 들어 키 체인의 코드에서 NSData로 필요하지만 Apple의 iPhone 구성 유틸리티 나 다른 MDM을 사용하여 배포 한 경우 – Chris

+1

예 - 아래 코드는 내가 사용하는 코드입니다. 선행 식별자로 필요하다면 실제로는 조금 더 많습니다. 형식 지정에 대해 유감스럽게 생각합니다. 그러나 주석은 코드에서 약간 어렵습니다. 자유롭게 질문을 만들어서 잘라내어 붙여 넣을 수 있습니다. CFDictionaryCreate(), SecItemCopyMatching(), SecIdentityGetTypeID() 캐스트 검사, CFDataRef der = SecCertificateCopyData (cert); const 부호없는 char * ptr = CFDataGetBytePtr (der); long len = CFDataGetLength (der); d2i_X509 (& x509, & ptr, len); _sha1 = [(__bridge NSData *) der sha1]; _der = (__bridge_transfer NSData *) der; CFRelease (der); –

+0

코드 (및 Apple의 예제 코드)를 사용해 보았지만 항상 SecTrustEvaluate에서 충돌합니다. 새 게시물 : http://stackoverflow.com/questions/11608847/always-exc-bad-access-on-sectrustevaluate – Chris