MYCertificate now checks validity of self-signed certs loaded from the keychain (because the Security framework doesn't validate self-signed certs.)
1.1 --- a/MYCertificate.m Wed Jul 01 14:19:13 2009 -0700
1.2 +++ b/MYCertificate.m Tue Jul 21 10:13:08 2009 -0700
1.3 @@ -14,6 +14,12 @@
1.4 #import "MYErrorUtils.h"
1.5
1.6
1.7 +@interface MYCertificate ()
1.8 +- (BOOL) _verify;
1.9 +@end
1.10 +
1.11 +
1.12 +
1.13 @implementation MYCertificate
1.14
1.15
1.16 @@ -22,6 +28,11 @@
1.17 self = [super initWithKeychainItemRef: (SecKeychainItemRef)certificateRef];
1.18 if (self) {
1.19 _certificateRef = certificateRef; // superclass has already CFRetained it
1.20 + if (![self _verify]) {
1.21 + Log(@"Self-signed cert failed signature verification (%@)", self);
1.22 + [self release];
1.23 + return nil;
1.24 + }
1.25 }
1.26 return self;
1.27 }
1.28 @@ -54,17 +65,10 @@
1.29 self = [self initWithCertificateRef: certificateRef];
1.30 CFRelease(certificateRef);
1.31
1.32 - // If the cert is self-signed, verify its signature. Apple's frameworks don't do this,
1.33 - // even the SecTrust API; if the signature doesn't verify, they just assume it could be
1.34 - // signed by a different cert. Seems like a bad decision to me, so I'll add the check:
1.35 - MYCertificateInfo *info = self.info;
1.36 - if (info.isRoot) {
1.37 - Log(@"Verifying self-signed certificate %@ ...", self);
1.38 - if (![info verifySignatureWithKey: self.publicKey]) {
1.39 - Log(@"Self-signed cert failed signature verification (%@)", self);
1.40 - [self release];
1.41 - return nil;
1.42 - }
1.43 + if (![self _verify]) {
1.44 + Log(@"Self-signed cert failed signature verification (%@)", self);
1.45 + [self release];
1.46 + return nil;
1.47 }
1.48
1.49 return self;
1.50 @@ -77,6 +81,7 @@
1.51 encoding: CSSM_CERT_ENCODING_BER];
1.52 }
1.53 #endif
1.54 +
1.55 - (void) dealloc
1.56 {
1.57 [_info release];
1.58 @@ -213,6 +218,15 @@
1.59 #pragma mark TRUST/POLICY STUFF:
1.60
1.61
1.62 +- (BOOL) _verify {
1.63 + // If the cert is self-signed, verify its signature. Apple's frameworks don't do this,
1.64 + // even the SecTrust API; if the signature doesn't verify, they just assume it could be
1.65 + // signed by a different cert. Seems like a bad decision to me, so I'll add the check:
1.66 + MYCertificateInfo *info = self.info;
1.67 + return !info.isRoot || [info verifySignatureWithKey: self.publicKey];
1.68 +}
1.69 +
1.70 +
1.71 - (SecTrustResultType) evaluateTrustWithPolicy: (SecPolicyRef)policy {
1.72 SecTrustRef trust;
1.73 if (!check(SecTrustCreateWithCertificates((CFArrayRef)$array((id)_certificateRef), policy, &trust),
2.1 --- a/MYCrypto.xcodeproj/project.pbxproj Wed Jul 01 14:19:13 2009 -0700
2.2 +++ b/MYCrypto.xcodeproj/project.pbxproj Tue Jul 21 10:13:08 2009 -0700
2.3 @@ -124,7 +124,7 @@
2.4 27B855250FD077A6005631F9 /* MYDEREncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYDEREncoder.h; sourceTree = "<group>"; };
2.5 27B855260FD077A6005631F9 /* MYDEREncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYDEREncoder.m; sourceTree = "<group>"; };
2.6 27CFF4B10F7E8535000B418E /* MYCertificate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYCertificate.h; sourceTree = "<group>"; };
2.7 - 27CFF4B20F7E8535000B418E /* MYCertificate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYCertificate.m; sourceTree = "<group>"; };
2.8 + 27CFF4B20F7E8535000B418E /* MYCertificate.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = MYCertificate.m; sourceTree = "<group>"; };
2.9 27CFF4B30F7E8535000B418E /* MYCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYCryptor.h; sourceTree = "<group>"; };
2.10 27CFF4B40F7E8535000B418E /* MYCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYCryptor.m; sourceTree = "<group>"; };
2.11 27CFF4B50F7E8535000B418E /* MYKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYKeychain.h; sourceTree = "<group>"; };
2.12 @@ -227,8 +227,10 @@
2.13 27EAF0390F8B2D700091AF95 /* README.textile */,
2.14 27FEB3E60FBA63D200290049 /* MYCrypto.h */,
2.15 );
2.16 + indentWidth = 4;
2.17 name = Source;
2.18 sourceTree = "<group>";
2.19 + usesTabs = 0;
2.20 };
2.21 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
2.22 isa = PBXGroup;
2.23 @@ -257,8 +259,10 @@
2.24 27CFF4B30F7E8535000B418E /* MYCryptor.h */,
2.25 27CFF4B40F7E8535000B418E /* MYCryptor.m */,
2.26 );
2.27 + indentWidth = 4;
2.28 name = Encryption;
2.29 sourceTree = "<group>";
2.30 + usesTabs = 0;
2.31 };
2.32 270B881C0F8D055A00C56781 /* Internal */ = {
2.33 isa = PBXGroup;
2.34 @@ -270,8 +274,10 @@
2.35 27CFF5400F7E9653000B418E /* MYCrypto_Debug.xcconfig */,
2.36 2748604D0F8D5C4C00FE617B /* MYCrypto_Release.xcconfig */,
2.37 );
2.38 + indentWidth = 4;
2.39 name = Internal;
2.40 sourceTree = "<group>";
2.41 + usesTabs = 0;
2.42 };
2.43 274861440F8D757600FE617B /* Certificates */ = {
2.44 isa = PBXGroup;
2.45 @@ -288,8 +294,10 @@
2.46 27B852FC0FCF4ECB005631F9 /* MYOID.h */,
2.47 27B852FD0FCF4ECB005631F9 /* MYOID.m */,
2.48 );
2.49 + indentWidth = 4;
2.50 name = Certificates;
2.51 sourceTree = "<group>";
2.52 + usesTabs = 0;
2.53 };
2.54 27CFF4CC0F7E86E8000B418E /* MYUtilities */ = {
2.55 isa = PBXGroup;
2.56 @@ -306,8 +314,10 @@
2.57 27CFF5750F7E999B000B418E /* MYErrorUtils.m */,
2.58 27CFF57C0F7EA117000B418E /* MYError_CSSMErrorDomain.strings */,
2.59 );
2.60 + indentWidth = 4;
2.61 name = MYUtilities;
2.62 sourceTree = MYUtilities;
2.63 + usesTabs = 0;
2.64 };
2.65 C6859EA2029092E104C91782 /* Documentation */ = {
2.66 isa = PBXGroup;