Adding tests for trusting derived certificates.
This commit is contained in:
parent
f1cfb96ad7
commit
5dcfe99c93
4 changed files with 138 additions and 0 deletions
|
|
@ -27,6 +27,10 @@
|
||||||
29A9CE2217456336002360C8 /* AFJSONRequestOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29A9CE2017456336002360C8 /* AFJSONRequestOperationTests.m */; };
|
29A9CE2217456336002360C8 /* AFJSONRequestOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29A9CE2017456336002360C8 /* AFJSONRequestOperationTests.m */; };
|
||||||
A70F4A96175A529400386DF5 /* root_certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A95175A529400386DF5 /* root_certificate.cer */; };
|
A70F4A96175A529400386DF5 /* root_certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A95175A529400386DF5 /* root_certificate.cer */; };
|
||||||
A70F4A97175A529400386DF5 /* root_certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A95175A529400386DF5 /* root_certificate.cer */; };
|
A70F4A97175A529400386DF5 /* root_certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A95175A529400386DF5 /* root_certificate.cer */; };
|
||||||
|
A70F4A9E175A726B00386DF5 /* ca.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A9C175A726B00386DF5 /* ca.cer */; };
|
||||||
|
A70F4A9F175A726B00386DF5 /* ca.cer in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A9C175A726B00386DF5 /* ca.cer */; };
|
||||||
|
A70F4AA0175A726B00386DF5 /* derived.cert in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A9D175A726B00386DF5 /* derived.cert */; };
|
||||||
|
A70F4AA1175A726B00386DF5 /* derived.cert in Resources */ = {isa = PBXBuildFile; fileRef = A70F4A9D175A726B00386DF5 /* derived.cert */; };
|
||||||
A7DC62A617592E4200EBEC2F /* AFTestURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */; };
|
A7DC62A617592E4200EBEC2F /* AFTestURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */; };
|
||||||
A7DC62A717592E4200EBEC2F /* AFTestURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */; };
|
A7DC62A717592E4200EBEC2F /* AFTestURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */; };
|
||||||
A7DC62A917592E4800EBEC2F /* AFURLConnectionOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A817592E4800EBEC2F /* AFURLConnectionOperationTests.m */; };
|
A7DC62A917592E4800EBEC2F /* AFURLConnectionOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A7DC62A817592E4800EBEC2F /* AFURLConnectionOperationTests.m */; };
|
||||||
|
|
@ -81,6 +85,8 @@
|
||||||
55E73C267F33406A9F92476C /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
55E73C267F33406A9F92476C /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
96A923755B00464187DEDBAF /* libPods-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
96A923755B00464187DEDBAF /* libPods-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A70F4A95175A529400386DF5 /* root_certificate.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = root_certificate.cer; path = Resources/root_certificate.cer; sourceTree = "<group>"; };
|
A70F4A95175A529400386DF5 /* root_certificate.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = root_certificate.cer; path = Resources/root_certificate.cer; sourceTree = "<group>"; };
|
||||||
|
A70F4A9C175A726B00386DF5 /* ca.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = ca.cer; path = Resources/ca.cer; sourceTree = "<group>"; };
|
||||||
|
A70F4A9D175A726B00386DF5 /* derived.cert */ = {isa = PBXFileReference; lastKnownFileType = file; name = derived.cert; path = Resources/derived.cert; sourceTree = "<group>"; };
|
||||||
A7DC62A417592E4200EBEC2F /* AFTestURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFTestURLProtocol.h; sourceTree = "<group>"; };
|
A7DC62A417592E4200EBEC2F /* AFTestURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFTestURLProtocol.h; sourceTree = "<group>"; };
|
||||||
A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFTestURLProtocol.m; sourceTree = "<group>"; };
|
A7DC62A517592E4200EBEC2F /* AFTestURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFTestURLProtocol.m; sourceTree = "<group>"; };
|
||||||
A7DC62A817592E4800EBEC2F /* AFURLConnectionOperationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperationTests.m; sourceTree = "<group>"; };
|
A7DC62A817592E4800EBEC2F /* AFURLConnectionOperationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperationTests.m; sourceTree = "<group>"; };
|
||||||
|
|
@ -222,6 +228,8 @@
|
||||||
A70F4A91175A4E0000386DF5 /* Certificates */ = {
|
A70F4A91175A4E0000386DF5 /* Certificates */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A70F4A9C175A726B00386DF5 /* ca.cer */,
|
||||||
|
A70F4A9D175A726B00386DF5 /* derived.cert */,
|
||||||
A70F4A95175A529400386DF5 /* root_certificate.cer */,
|
A70F4A95175A529400386DF5 /* root_certificate.cer */,
|
||||||
);
|
);
|
||||||
name = Certificates;
|
name = Certificates;
|
||||||
|
|
@ -300,6 +308,8 @@
|
||||||
files = (
|
files = (
|
||||||
F8C6F282174D2C6200B154D5 /* Icon.png in Resources */,
|
F8C6F282174D2C6200B154D5 /* Icon.png in Resources */,
|
||||||
A70F4A96175A529400386DF5 /* root_certificate.cer in Resources */,
|
A70F4A96175A529400386DF5 /* root_certificate.cer in Resources */,
|
||||||
|
A70F4A9E175A726B00386DF5 /* ca.cer in Resources */,
|
||||||
|
A70F4AA0175A726B00386DF5 /* derived.cert in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -309,6 +319,8 @@
|
||||||
files = (
|
files = (
|
||||||
F8C6F283174D2C6200B154D5 /* Icon.png in Resources */,
|
F8C6F283174D2C6200B154D5 /* Icon.png in Resources */,
|
||||||
A70F4A97175A529400386DF5 /* root_certificate.cer in Resources */,
|
A70F4A97175A529400386DF5 /* root_certificate.cer in Resources */,
|
||||||
|
A70F4A9F175A726B00386DF5 /* ca.cer in Resources */,
|
||||||
|
A70F4AA1175A726B00386DF5 /* derived.cert in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -180,4 +180,130 @@
|
||||||
expect(useCredentialInvoked).will.beTruthy();
|
expect(useCredentialInvoked).will.beTruthy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testThatAFURLConnectionOperationTrustsPublicKeysOfDerivedCertificates {
|
||||||
|
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/path" relativeToURL:self.baseURL]];
|
||||||
|
AFURLConnectionOperation *operation = [[AFURLConnectionOperation alloc] initWithRequest:request];
|
||||||
|
operation.SSLPinningMode = AFSSLPinningModePublicKey;
|
||||||
|
|
||||||
|
__block BOOL useCredentialInvoked = NO;
|
||||||
|
|
||||||
|
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:request.URL.host port:request.URL.port.integerValue protocol:request.URL.scheme realm:nil authenticationMethod:NSURLAuthenticationMethodServerTrust];
|
||||||
|
|
||||||
|
NSData *caCertificateData = [NSData dataWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"ca" ofType:@"cer"]];
|
||||||
|
NSParameterAssert(caCertificateData);
|
||||||
|
|
||||||
|
SecCertificateRef caCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCertificateData);
|
||||||
|
NSParameterAssert(caCertificate);
|
||||||
|
|
||||||
|
NSData *hostCertificateData = [NSData dataWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"derived" ofType:@"cert"]];
|
||||||
|
NSParameterAssert(hostCertificateData);
|
||||||
|
|
||||||
|
SecCertificateRef hostCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCertificateData);
|
||||||
|
NSParameterAssert(hostCertificate);
|
||||||
|
|
||||||
|
SecCertificateRef allowedCertificates[] = {caCertificate, hostCertificate};
|
||||||
|
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 2, NULL);
|
||||||
|
|
||||||
|
SecPolicyRef policy = SecPolicyCreateBasicX509();
|
||||||
|
SecTrustRef trust = NULL;
|
||||||
|
OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust);
|
||||||
|
NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
|
||||||
|
|
||||||
|
SecTrustResultType result;
|
||||||
|
status = SecTrustEvaluate(trust, &result);
|
||||||
|
NSAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||||
|
|
||||||
|
id mockedProtectionSpace = [OCMockObject partialMockForObject:protectionSpace];
|
||||||
|
|
||||||
|
[[[mockedProtectionSpace stub] andDo:^(NSInvocation *invocation) {
|
||||||
|
[invocation setReturnValue:(void *)&trust];
|
||||||
|
}] serverTrust];
|
||||||
|
|
||||||
|
AFTestURLProtocol *protocol = [[AFTestURLProtocol alloc] initWithRequest:request cachedResponse:nil client:nil];
|
||||||
|
id mockedProtocol = [OCMockObject partialMockForObject:protocol];
|
||||||
|
|
||||||
|
void(^useCredential)(NSInvocation *invocation) = ^(NSInvocation *invocation) {
|
||||||
|
useCredentialInvoked = YES;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[[mockedProtocol stub] andDo:useCredential] useCredential:OCMOCK_ANY forAuthenticationChallenge:OCMOCK_ANY];
|
||||||
|
|
||||||
|
NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:trust];
|
||||||
|
NSURLAuthenticationChallenge *authenticationChallenge = [[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:protectionSpace proposedCredential:credential previousFailureCount:0 failureResponse:nil error:nil sender:mockedProtocol];
|
||||||
|
[protocol.client URLProtocol:mockedProtocol didReceiveAuthenticationChallenge:authenticationChallenge];
|
||||||
|
|
||||||
|
[operation connection:nil willSendRequestForAuthenticationChallenge:authenticationChallenge];
|
||||||
|
|
||||||
|
CFRelease(trust);
|
||||||
|
CFRelease(policy);
|
||||||
|
CFRelease(certificates);
|
||||||
|
CFRelease(caCertificate);
|
||||||
|
CFRelease(hostCertificate);
|
||||||
|
|
||||||
|
expect(useCredentialInvoked).will.beTruthy();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testThatAFURLConnectionOperationTrustsDerivedCertificates {
|
||||||
|
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"/path" relativeToURL:self.baseURL]];
|
||||||
|
AFURLConnectionOperation *operation = [[AFURLConnectionOperation alloc] initWithRequest:request];
|
||||||
|
operation.SSLPinningMode = AFSSLPinningModeCertificate;
|
||||||
|
|
||||||
|
__block BOOL useCredentialInvoked = NO;
|
||||||
|
|
||||||
|
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:request.URL.host port:request.URL.port.integerValue protocol:request.URL.scheme realm:nil authenticationMethod:NSURLAuthenticationMethodServerTrust];
|
||||||
|
|
||||||
|
NSData *caCertificateData = [NSData dataWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"ca" ofType:@"cer"]];
|
||||||
|
NSParameterAssert(caCertificateData);
|
||||||
|
|
||||||
|
SecCertificateRef caCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCertificateData);
|
||||||
|
NSParameterAssert(caCertificate);
|
||||||
|
|
||||||
|
NSData *hostCertificateData = [NSData dataWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"derived" ofType:@"cert"]];
|
||||||
|
NSParameterAssert(hostCertificateData);
|
||||||
|
|
||||||
|
SecCertificateRef hostCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCertificateData);
|
||||||
|
NSParameterAssert(hostCertificate);
|
||||||
|
|
||||||
|
SecCertificateRef allowedCertificates[] = {caCertificate, hostCertificate};
|
||||||
|
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 2, NULL);
|
||||||
|
|
||||||
|
SecPolicyRef policy = SecPolicyCreateBasicX509();
|
||||||
|
SecTrustRef trust = NULL;
|
||||||
|
OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust);
|
||||||
|
NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
|
||||||
|
|
||||||
|
SecTrustResultType result;
|
||||||
|
status = SecTrustEvaluate(trust, &result);
|
||||||
|
NSAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||||
|
|
||||||
|
id mockedProtectionSpace = [OCMockObject partialMockForObject:protectionSpace];
|
||||||
|
|
||||||
|
[[[mockedProtectionSpace stub] andDo:^(NSInvocation *invocation) {
|
||||||
|
[invocation setReturnValue:(void *)&trust];
|
||||||
|
}] serverTrust];
|
||||||
|
|
||||||
|
AFTestURLProtocol *protocol = [[AFTestURLProtocol alloc] initWithRequest:request cachedResponse:nil client:nil];
|
||||||
|
id mockedProtocol = [OCMockObject partialMockForObject:protocol];
|
||||||
|
|
||||||
|
void(^useCredential)(NSInvocation *invocation) = ^(NSInvocation *invocation) {
|
||||||
|
useCredentialInvoked = YES;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[[mockedProtocol stub] andDo:useCredential] useCredential:OCMOCK_ANY forAuthenticationChallenge:OCMOCK_ANY];
|
||||||
|
|
||||||
|
NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:trust];
|
||||||
|
NSURLAuthenticationChallenge *authenticationChallenge = [[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:protectionSpace proposedCredential:credential previousFailureCount:0 failureResponse:nil error:nil sender:mockedProtocol];
|
||||||
|
[protocol.client URLProtocol:mockedProtocol didReceiveAuthenticationChallenge:authenticationChallenge];
|
||||||
|
|
||||||
|
[operation connection:nil willSendRequestForAuthenticationChallenge:authenticationChallenge];
|
||||||
|
|
||||||
|
CFRelease(trust);
|
||||||
|
CFRelease(policy);
|
||||||
|
CFRelease(certificates);
|
||||||
|
CFRelease(caCertificate);
|
||||||
|
CFRelease(hostCertificate);
|
||||||
|
|
||||||
|
expect(useCredentialInvoked).will.beTruthy();
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
BIN
Tests/Resources/ca.cer
Normal file
BIN
Tests/Resources/ca.cer
Normal file
Binary file not shown.
BIN
Tests/Resources/derived.cert
Normal file
BIN
Tests/Resources/derived.cert
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue