Skip to content

Recent Articles

17
May

Validating a Self-Signed SSL Certificate in iOS and OS X Against a Changing Host Name

We developed a device with which we communicate securely over SSL using a self-signed certificate. The device gets a dynamically-assigned IP address, and that is communicated to the iOS app via other means. By default, NSURLConnection tries to validate the SSL certificate against the hostname, but it was impossible for us to create a wildcard cert that would match.

So instead, I figured out how to get Security.framework to ignore the host name. You must use the supplied trust’s certificate chain to create a new trust, which allows you to specify the trust policy. You then set the root (anchor) cert that was used to sign the self-signed cert. In our case, these are one and the same (an explanation of how to do this is included below).

- (void)
connection: (NSURLConnection*) inConnection
    willSendRequestForAuthenticationChallenge: (NSURLAuthenticationChallenge*) inChallenge
{
    NSLogDebug(@"Connection challenged");

    //  Build a new trust based on the supplied trust, so that we can set the policy…

    NSURLProtectionSpace* protectionSpace = inChallenge.protectionSpace;
    SecTrustRef trust = protectionSpace.serverTrust;

    CFIndex numCerts = SecTrustGetCertificateCount(trust);
    NSMutableArray* certs = [NSMutableArray arrayWithCapacity: numCerts];
    for (CFIndex idx = 0; idx < numCerts; ++idx)
    {
        SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, idx);
        [certs addObject: CFBridgingRelease(cert)];
    }

    //  Create a policy that ignores the host name…

    SecPolicyRef policy = SecPolicyCreateSSL(true, NULL);
    OSStatus err = SecTrustCreateWithCertificates(CFBridgingRetain(certs), policy, &trust);
    CFRelease(policy);
    if (err != noErr)
    {
        NSLogDebug(@"Error creating trust: %d", err);
        [inChallenge.sender cancelAuthenticationChallenge: inChallenge];
        return;
    }

    //  Set the root cert and evaluate the trust…

    NSArray* rootCerts = @[ CFBridgingRelease(mRootCert) ];
    err = SecTrustSetAnchorCertificates(trust, CFBridgingRetain(rootCerts));
    if (err == noErr)
    {
        SecTrustResultType trustResult;
        err = SecTrustEvaluate(trust, &trustResult);
        NSURLCredential* credential = [NSURLCredential credentialForTrust: trust];
        CFRelease(trust);

        bool trusted = err == noErr;
        trusted = trusted && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified);
        if (trusted)
        {
            [inChallenge.sender useCredential: credential forAuthenticationChallenge: inChallenge];
            return;
        }
    }

    //  An error occurred, or we don't trust the cert, so disallow it…

    [inChallenge.sender cancelAuthenticationChallenge: inChallenge];
}

Chances are, when you created your self-signed cert, you did something like this:

$ openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout my.key -out my.crt

That produces a certificate in PEM format (ASCII). Security.framework requires the certificate in DER format. You can convert the cert with the following (note that this will overwrite the PEM cert you generated):

$ openssl x509 -in my.crt -outform der -out my.crt

You can create the root SecCertificateRef with something like this:

- (void)
createRootCert
{
    NSURL* certURL = [[NSBundle mainBundle] URLForResource: @"my" withExtension: @"crt"];
    NSData* certData = [NSData dataWithContentsOfURL: certURL];
    mRootCert = SecCertificateCreateWithData(kCFAllocatorDefault, CFBridgingRetain(certData));
}
23
Apr

Cheap Chinese Reflow Oven

I bought the T962A many months ago, and finally got around to using it. I ended up scorching boards and parts, so I decided to measure the actual temperatures reached on a few of the curves.

Because I was using lead-free solder paste, I chose a lead-free profile. Typically lead-free solders have to be heated more than leaded solders. Unfortunately, it turns out the oven runs very hot. Here are temperatures take for the first three built-in profiles (“Wave 1″ to “Wave 3″). In the first, I had thermocouples in contact (or close to it) with the top and bottom surfaces of a 120 mm X 100 mm, four-layer board. In the subsequent two, I also had a third thermocouple a few millimeters above the top surface, although its positioning wasn’t consistent from one run to the next.

I also opened the windows and ran a fan over the oven during the cool-down periods of the last two runs. This was because I could smell burning in the room, and although there was no paste in these runs, who knows what noxious things were burning off the oven.

In each graph, I show the programmed maximum temperature and duration.

Wave1

Wave2

Wave3
Read moreRead more

8
Nov

2012 vs 2008

The 2012 elections are over, thankfully. Here’s a comparison of how the country voted using more representative visualizations, and comparing the results to 2008.

These maps come from Mark Newman, Department of Physics and Center for the Study of Complex Systems, University of Michigan.

Purple Electoral Map (click to enlarge):

Purple Cartogram (click to enlarge):