A First Look at MintChip's Hosted API's Crypto

April 07, 2012 at 08:05 PM | OpenSSL, MintChip | View Comments

The Royal Canadian Mint announced a challenge last week, calling for developers to build software which uses MintChip. MintChip is a proposed digital currency which is decentralized, anonymous, and offline. The (currently scarce) details of the device and developer challenge can be found at mintchipchallenge.com.

A couple of friends and I have signed up to build something, and we just got the private keys and certificates necessary to interact with the "hosted MintChip" API.

Overview

Before I go into more detail, let me first explain: payments are processed by the "trusted"[0] MintChip hardware. This hardware can either be attached directly to the device facilitating a payment (for example, a smart phone), or hosted by a trusted 3rd party, allowing the MintChip to be used from any internet-connected device.

This is called the "hosted API", and this post deals with the cryptography used for authentication and privacy by the current implementation of the hosted API.

Once my physical devices arrive, I will write a post about them, provided they are sufficiently interesting.

[0]: at least, trusted in theory; if the hardware is compromised it would be possible to forge transactions (ex, double-spend, create new money, etc).

The Hosted API

Important notes:

  • Everything here is educated guesswork, based only on the sparse MintChip documentation and the PKCS12 file which is used to access the hosted API.
  • I am an x509 enthusiast but not an expert. If you are, I would very much appreciate it if you pointed out any inaccuracies or omissions.
  • This is a developer preview of a proof-of-concept. There is no guarantee that the security of the final system will look anything at all like the system I'm describing here.

The first thing you'll notice when trying to access the hosted HTTPS API is that it signed with an "invalid" certificate (although this is for a sensible reason; keep reading):

$ curl https://remote.mintchipchallenge.com
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html

And connecting anyway yields a 403 Forbidden (also, that they are running ASP.NET):

$ curl -Ik https://remote.mintchipchallenge.com
HTTP/1.1 403 Forbidden
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET

HTTPS Server Certificate

Grabbing and dumping the certificate they are using:

$ openssl s_client -connect remote.mintchipchallenge.com:443 -showcerts \
> | openssl x509 -noout -text
...
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
        Validity
            Not Before: Mar  6 08:25:42 2012 GMT
            Not After : Mar  7 08:25:42 2013 GMT
        Subject: CN=remote.mintchipchallenge.com, OU=Remote MintChip Server, O=Royal Canadian Mint, C=CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:8e:1c:52:2f:c7:62:7d:05:0b:4a:80:4f:cb:91:
                    ...
                    5a:90:60:58:f9:43:c8:bc:f1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Key Encipherment, Key Agreement
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
    Signature Algorithm: sha1WithRSAEncryption
        58:34:a3:bd:f3:8d:17:b2:eb:4e:ed:f6:58:b0:13:3b:8c:79:
        ...
        91:0d:59:81
...

Note that the certificate is issued by "Remote MintChip Authority". I suspect that MintChip chose to use their own CA both for simplicity (they don't need to deal with a 3rd party) and security. Apart from that, this certificate looks fairly standard (although I don't fully understand the implications of the "Key Agreement" flag).

Developer Account PKCS12 Files

Next, once my developer account[0] was approved, I was sent two PKCS12 files (and the passwords used to decrypt them), corresponding to (I assume) two hosted MintChips.

[0]: actually, my friend's developer account - mine hasn't been approved yet.

Unpacking each of these PKCS12 files yields one private key and two certificates:

$ openssl pkcs12 -nodes -passin pass:hunter2 -info -in 1310000000008139.p12
MAC Iteration 1024
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Bag Attributes
    localKeyID: 82 8F 5D AD 42 DC C9 EA 25 2C 6E 65 C0 DB B8 20 52 7D 1D 15
    friendlyName: 1310000000008139 Remote MintChip Client (Developer Challenge)
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 1024
Certificate bag
Bag Attributes
    localKeyID: 82 8F 5D AD 42 DC C9 EA 25 2C 6E 65 C0 DB B8 20 52 7D 1D 15
    friendlyName: 1310000000008139 Remote MintChip Client (Developer Challenge)
subject=/CN=1310000000008139/OU=Remote MintChip Client/O=Royal Canadian Mint/C=CA
issuer=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes
    friendlyName: Remote MintChip CA (Developer Challenge)
subject=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
issuer=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

The Private Key

As far as I can tell there is nothing noteworthy about the private key.

The Client Authentication Certificate

Inspecting the first of the two certificates yields:

$ echo "$FIRST_CERT" | openssl x509 -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1198 (0x4ae)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
        Validity
            Not Before: Mar  6 10:06:45 2012 GMT
            Not After : Mar  7 10:06:45 2013 GMT
        Subject: CN=1310000000008139, OU=Remote MintChip Client, O=Royal Canadian Mint, C=CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:a7:1b:d9:81:17:ce:ae:b7:e8:46:6c:51:6b:b8:
                    ...
                    62:20:0b:93:f7:02:4c:c5:dd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
    Signature Algorithm: sha1WithRSAEncryption
        67:b9:d1:47:c2:62:82:60:1d:f9:01:04:de:c6:db:19:f3:3e:
        ...
        17:16:60:0f

As can be seen by the "Extended Key Usage" extension, this certificate will be used for client-side certificate authentication.

I think this is pretty cool. When password protected, client-side certificates provide a nifty and unobtrusive form of two-factor authentication. I've only ever seen them used "in the wild" by CACert, so it's fun to see someone else using them.

As before, this certificate is signed by the "Remote MintChip Certificate Authority".

Nothing else is particularly surprising.

The Certificate Authority's Certificate

Now, on to the second certificate:

$ echo "$SECOND_CERT" | openssl x509 -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
        Validity
            Not Before: Mar  6 08:25:36 2012 GMT
            Not After : Mar  7 08:25:36 2017 GMT
        Subject: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:ab:d9:7b:dc:a8:eb:55:59:05:46:23:ef:4d:76:
                    ...
                    9a:c1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:TRUE
            X509v3 Key Usage:
                Certificate Sign
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
    Signature Algorithm: sha1WithRSAEncryption
        41:95:6f:94:9a:3e:9d:03:af:a3:22:d6:0f:b6:7a:08:91:9d:
        ...
        b3:da:88:bf

This is the certificate of the "Remote MintChip Certificate Authority" that has signed all the other certificates we've looked at.

Unlike all the other certificates we've looked at, though, this certificate is surprising: this certificate needs to be[0] added to the list of trusted CAs on all the devices which will use the MintChip hosted API... But it doesn't include any name constraints! [1] This means that, if the CA's private key was compromised, it could be used to forge certificates that would be trusted by any device which trusts this CA.

I find this omission a bit surprising; the hosted API's security appears to be well designed, which makes it seem unlikely that this was accidental.

Because the system is otherwise intelligent, I'm inclined to give MintChip the benefit of the doubt here, and assume that there is a good reason for omitting the name constraints. This is a developer-only preview of a proof-of-concept system, so it's possible they will be changing domains or using this CA in as-of-yet unexpected ways.

Edit: after some experimentaton, it seems that there is a less mysterious reason for the CA's lack of name constraints: they are ignored. For more details, see "Adventures in X.509: The Utterly Ignored nameConstraints".

[0]: or, at least, "really should be"
[1]: RFC 2459 section 4.2.1.11, "Name Constraints".

tl;dr

The MintChip hosted API uses SSL client certificates for authentication, and both client and server certificates are signed by MintChip's own self-signed certificate authority.