# HG changeset patch # User Jens Alfke # Date 1248196388 25200 # Node ID d0aadddb9c641e794a2158245fe4492a1c96eb7e # Parent d9c2a06d4e4ef9786232f7b59621ff8e3aad87a1 MYCertificate now checks validity of self-signed certs loaded from the keychain (because the Security framework doesn't validate self-signed certs.) diff -r d9c2a06d4e4e -r d0aadddb9c64 MYCertificate.m --- a/MYCertificate.m Wed Jul 01 14:19:13 2009 -0700 +++ b/MYCertificate.m Tue Jul 21 10:13:08 2009 -0700 @@ -14,6 +14,12 @@ #import "MYErrorUtils.h" +@interface MYCertificate () +- (BOOL) _verify; +@end + + + @implementation MYCertificate @@ -22,6 +28,11 @@ self = [super initWithKeychainItemRef: (SecKeychainItemRef)certificateRef]; if (self) { _certificateRef = certificateRef; // superclass has already CFRetained it + if (![self _verify]) { + Log(@"Self-signed cert failed signature verification (%@)", self); + [self release]; + return nil; + } } return self; } @@ -54,17 +65,10 @@ self = [self initWithCertificateRef: certificateRef]; CFRelease(certificateRef); - // If the cert is self-signed, verify its signature. Apple's frameworks don't do this, - // even the SecTrust API; if the signature doesn't verify, they just assume it could be - // signed by a different cert. Seems like a bad decision to me, so I'll add the check: - MYCertificateInfo *info = self.info; - if (info.isRoot) { - Log(@"Verifying self-signed certificate %@ ...", self); - if (![info verifySignatureWithKey: self.publicKey]) { - Log(@"Self-signed cert failed signature verification (%@)", self); - [self release]; - return nil; - } + if (![self _verify]) { + Log(@"Self-signed cert failed signature verification (%@)", self); + [self release]; + return nil; } return self; @@ -77,6 +81,7 @@ encoding: CSSM_CERT_ENCODING_BER]; } #endif + - (void) dealloc { [_info release]; @@ -213,6 +218,15 @@ #pragma mark TRUST/POLICY STUFF: +- (BOOL) _verify { + // If the cert is self-signed, verify its signature. Apple's frameworks don't do this, + // even the SecTrust API; if the signature doesn't verify, they just assume it could be + // signed by a different cert. Seems like a bad decision to me, so I'll add the check: + MYCertificateInfo *info = self.info; + return !info.isRoot || [info verifySignatureWithKey: self.publicKey]; +} + + - (SecTrustResultType) evaluateTrustWithPolicy: (SecPolicyRef)policy { SecTrustRef trust; if (!check(SecTrustCreateWithCertificates((CFArrayRef)$array((id)_certificateRef), policy, &trust), diff -r d9c2a06d4e4e -r d0aadddb9c64 MYCrypto.xcodeproj/project.pbxproj --- a/MYCrypto.xcodeproj/project.pbxproj Wed Jul 01 14:19:13 2009 -0700 +++ b/MYCrypto.xcodeproj/project.pbxproj Tue Jul 21 10:13:08 2009 -0700 @@ -124,7 +124,7 @@ 27B855250FD077A6005631F9 /* MYDEREncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYDEREncoder.h; sourceTree = ""; }; 27B855260FD077A6005631F9 /* MYDEREncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYDEREncoder.m; sourceTree = ""; }; 27CFF4B10F7E8535000B418E /* MYCertificate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYCertificate.h; sourceTree = ""; }; - 27CFF4B20F7E8535000B418E /* MYCertificate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYCertificate.m; sourceTree = ""; }; + 27CFF4B20F7E8535000B418E /* MYCertificate.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = MYCertificate.m; sourceTree = ""; }; 27CFF4B30F7E8535000B418E /* MYCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYCryptor.h; sourceTree = ""; }; 27CFF4B40F7E8535000B418E /* MYCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYCryptor.m; sourceTree = ""; }; 27CFF4B50F7E8535000B418E /* MYKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYKeychain.h; sourceTree = ""; }; @@ -227,8 +227,10 @@ 27EAF0390F8B2D700091AF95 /* README.textile */, 27FEB3E60FBA63D200290049 /* MYCrypto.h */, ); + indentWidth = 4; name = Source; sourceTree = ""; + usesTabs = 0; }; 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; @@ -257,8 +259,10 @@ 27CFF4B30F7E8535000B418E /* MYCryptor.h */, 27CFF4B40F7E8535000B418E /* MYCryptor.m */, ); + indentWidth = 4; name = Encryption; sourceTree = ""; + usesTabs = 0; }; 270B881C0F8D055A00C56781 /* Internal */ = { isa = PBXGroup; @@ -270,8 +274,10 @@ 27CFF5400F7E9653000B418E /* MYCrypto_Debug.xcconfig */, 2748604D0F8D5C4C00FE617B /* MYCrypto_Release.xcconfig */, ); + indentWidth = 4; name = Internal; sourceTree = ""; + usesTabs = 0; }; 274861440F8D757600FE617B /* Certificates */ = { isa = PBXGroup; @@ -288,8 +294,10 @@ 27B852FC0FCF4ECB005631F9 /* MYOID.h */, 27B852FD0FCF4ECB005631F9 /* MYOID.m */, ); + indentWidth = 4; name = Certificates; sourceTree = ""; + usesTabs = 0; }; 27CFF4CC0F7E86E8000B418E /* MYUtilities */ = { isa = PBXGroup; @@ -306,8 +314,10 @@ 27CFF5750F7E999B000B418E /* MYErrorUtils.m */, 27CFF57C0F7EA117000B418E /* MYError_CSSMErrorDomain.strings */, ); + indentWidth = 4; name = MYUtilities; sourceTree = MYUtilities; + usesTabs = 0; }; C6859EA2029092E104C91782 /* Documentation */ = { isa = PBXGroup;