certificateTests.m

This file can be downloaded as part of milnlicence.tbz.

//
//  certificateTests.m
//  LicenceCore - https://indie.miln.eu
//
//  Copyright © Graham Miln. All rights reserved. https://miln.eu
//
//  This package is subject to the terms of the Artistic License 2.0.
//  If a copy of the Artistic-2.0 was not distributed with this file, you can
//  obtain one at https://indie.miln.eu/licence

@import XCTest;
@import LicenceCore;
#import "LCLicenceCorePrivate.h"

// Issued cert by https://sandbox.miln.eu/ca/appmember.cer
static NSString* appmemberCert = @"-----BEGIN CERTIFICATE-----\nMIIDfjCCAmagAwIBAgIEDAdZKzANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJG\nUjEVMBMGA1UEChMMTWlsbiBTYW5kYm94MRwwGgYDVQQLExNNaWxuIEFwcCBNZW1i\nZXJzaGlwMScwJQYDVQQDEx5NaWxuIEFwcCBNZW1iZXJzaGlwIElzc3VpbmcgQ0Ex\nEjAQBgNVBAUTCTUzOTc3ODc3OTAeFw0xODA4MTcwNzUyMTdaFw0xODExMTkwODUy\nMTdaMGIxETAPBgNVBAoTCFBlcnNvbmFsMScwJQYDVQQLEx5NaWxuIEFwcCBNZW1i\nZXJzaGlwIC0gMyBtb250aHMxJDAiBgNVBAMTG01pbG4gQXBwIE1lbWJlcjogdGVz\ndCBidXllcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs55jDkZ8q+wWDBEi\niEpsOvzYHQrN1CJMbcVN80eu7Ib+g0oN3WfaQsilnbQOtUF056RaSbxLT5Bremu1\nbEm+P7iGYVQ/lqvydeue6YezQonYPOzl87q6TT88k339UstC8eHE9H3HYr7xSeFh\n2Ny2XilxzMbvte8PPMNABhlBwn0CAwEAAaOBojCBnzAOBgNVHQ8BAf8EBAMCB4Aw\nDAYDVR0TAQH/BAIwADBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAKGKGh0dHBz\nOi8vc2FuZGJveC5taWxuLmV1L2NhL2FwcG1lbWJlci5jZXIwOQYDVR0fBDIwMDAu\noCygKoYoaHR0cHM6Ly9zYW5kYm94Lm1pbG4uZXUvY2EvYXBwbWVtYmVyLmNybDAN\nBgkqhkiG9w0BAQsFAAOCAQEAqnmSemLCo+f0phycnyPkBnrvM4E8jZa1QPEE4Ane\np3uKzWPR1AAi9MOjZUetAb6PPW2C5z0X/K71B0mxMeZCMCx77KroAtaB99grSv9T\nfr+5fhwtfwPfprYn6Jktj+vcko0OVS6tElI/5mFzKacfNY5JPvzeqzxghmAUziH3\nm2/Q+eb+xg6VzUmD22L4igDe69aK2agLm/1vHQ7VNmHGn0VdC8sKoJ5cq5buWaIa\n+Gk+4uyvxFnWQQrvibm1O27wJ1c5SV5C2MpjbCTx7xQdl738t5s8g1DaYbO/NvY2\nMxjk/far7wQcdf5xgwJ3ZiombX4s8GN4UHdmNWkNwX5O7w==\n-----END CERTIFICATE-----";

// Contains both OCSP and issuer URLs
static NSString* multiPEM = @"-----BEGIN CERTIFICATE-----\nMIIEcjCCAmCgAwIBAgIEDAdVpzANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJG\nUjEXMBUGA1UEChMOTXkgQ29tcGFueSBJbmMxHzAdBgNVBAMTFk15IENvbXBhbnkg\nSW5jIFJvb3QgQ0ExEjAQBgNVBAUTCTEyMzEyMzEyMzAeFw0xODA3MjcwNzI1NDBa\nFw0zODA3MTcwOTIyMjhaMEoxETAPBgNVBAoTCFBlcnNvbmFsMSAwHgYDVQQLExdN\nZW1iZXJzaGlwIC0gTWFueSBZZWFyczETMBEGA1UEAxMKdGVzdCBidXllcjCBnzAN\nBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvqe7lPuaLIw/DbvUzZXKP/mYAhryiBxI\npxXW7ayQPqU28Vz+j1EZAkrC3yBQ/lyGxWI6VzkAvOn+IELPUuQ0xr4qOML3vAZK\nEtOjCXgal+w0ask3yOZNbhoHE9q/QGm6QmLfgRsttK/BnJZrA5Wt82j7uuVjRzhA\nE6qcHpzjuN0CAwEAAaOB2DCB1TAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIw\nADB5BggrBgEFBQcBAQRtMGswNgYIKwYBBQUHMAGGKmh0dHBzOi8vc2FuZGJveC5k\nc3N3LnVrL2NhL21lbWJlcnNoaXAvb2NzcDAxBggrBgEFBQcwAoYlaHR0cHM6Ly9z\nYW5kYm94LmRzc3cudWsvY2EvbWVtYmVyc2hpcDA6BgNVHR8EMzAxMC+gLaArhilo\ndHRwczovL3NhbmRib3guZHNzdy51ay9jYS9tZW1iZXJzaGlwL2NybDANBgkqhkiG\n9w0BAQsFAAOCAfsAXhc9D5Tmw9OFUi2Ob/f2O3cH7j2YjwQs27KFBnAxol5OVqm7\nWZQysJGxLKZvWsZsnvAmjG5faBm4ol0GSzdn6vkDAJPaW6Bvj+vJ9Gu3/PGq4cpy\nj5F8AtrD6+MfYLgEo4APwicWWuTMEwKTrOKsP07fXhAlNjSyJzC8PGJva2NdkFJd\nNnvzhFElCMVBm7csXHxMq9mzlAdUOtoHUZv36+4dErB6RhkkvzA8LN3KvgXrd36Q\nqZCfA8ghLqrJJZa+7Rs8aC91At69h+PfkpkqhWI6DDoia5CWLid+la7Jnd8rK15v\nF4ygpYSiCb90CMHjZGamOi9gbIBU9PKXm4052359Q1z/pcMyNbkUdeInLAcSrjyh\nn7mB3nBompIpoBtVxTZu99Ain+bBt7ndWDJOi2ci9nOFoAdjsmu1rEmNWoC8vPdK\nb2idyGKu7LdDqXYtY1iPf/tt1emuudmO7qEEwQz2cEOvsvgzpA71eQB/8Xa4Ie//\nNIDgPVrxmmYuUA7zP/z0Bm7McENtzlRyHx3Ww4yzMWeLxzDfOj+DtdtIMAuq7qZA\ndpDXmIsT9qXQy5tahBDbz+Xfg9wbjVHzIpvYDrHxb/99zzrbUgGXrs1MslwCbxPl\n6B8BunoYlxIHcZ1FyJQFNEDncxqO3c4trf43LhsYDy0GmAB+e3E=\n-----END CERTIFICATE-----\n";

@interface certificateTests : XCTestCase
@end

@implementation certificateTests

- (void)testCertificate {
	NSData* pemData = [appmemberCert dataUsingEncoding:NSUTF8StringEncoding];
	
	// Create a SecCertificateRef for appmember
	SecCertificateRef certificate = nil;
	SecExternalFormat inputFormat = kSecFormatPEMSequence;
	SecExternalItemType itemType = kSecItemTypeCertificate;
	CFArrayRef importedItems = nil;
	OSStatus validImport = SecItemImport((CFDataRef)pemData,nil, &inputFormat, &itemType, 0, nil, nil, &importedItems);
	XCTAssertEqual(validImport, errSecSuccess, @"Import error.");

	// Ensure single certificate
	CFIndex i = CFArrayGetCount(importedItems);
	XCTAssertEqual(i, 1, @"Unexpected licence count.");
	
	// Extract and retain certificate
	CFTypeRef potentialCert = CFArrayGetValueAtIndex(importedItems, 0);
	if (potentialCert != nil && CFGetTypeID(potentialCert) == SecCertificateGetTypeID()) {
		certificate = (SecCertificateRef) CFRetain(potentialCert); // retain to hold onto the certificate
	}
	
	if (importedItems != NULL) {
		CFRelease(importedItems);
	}
	
	LCLicenceCore* lc = [LCLicenceCore new];
	NSError* chainError = nil;
	CFArrayRef chain = [lc createCertificateChainFor:certificate error:&chainError];
	XCTAssertNil(chainError, @"Chain error");
	
	if (certificate != NULL) {
		CFRelease(certificate);
	}
	
	XCTAssertTrue(chain != nil, @"Chain created");
	NSLog(@"chain: %@", (__bridge NSArray*)chain);
	
	if (chain != nil) {
		CFRelease(chain);
	}
}

/*
- (void)testCertificateURL {

	LCLicenceCore* lc = [LCLicenceCore new];
	NSError* certError = nil;
	SecCertificateRef cert = [lc createCertificateFromData:[multiPEM dataUsingEncoding:NSUTF8StringEncoding] error:&certError];
	XCTAssertNil(certError, @"certificate decode error");
	XCTAssertTrue(cert != NULL, @"cert created");
	
	LCCertificateChainAssistant* assistant = [LCCertificateChainAssistant new];
	NSError* urlError = nil;
	NSURL* url = [assistant issuingCertificateURLForCertificate:cert error:&urlError];
	XCTAssertNil(urlError, @"issuer url error");
	XCTAssertNotNil(url, @"url extracted");
	
	NSURL* expected = [NSURL URLWithString:@"https://sandbox.dssw.uk/ca/membership"];
	XCTAssertEqualObjects(url, expected, @"issuer url ok");
}
*/

@end