MUST STAPLE and PKI.js

The other day I did a post on how to create a self-signed certificate using PKI.js in that sample we included a Basic Constraints extension but we could have also just as easily defined a custom or new certificate extension. For example thanks to #heartbleed folks are talking about MUST STAPLE again, this is an extension that was proposed several years ago that when present would indicate that clients should hard-fail instead of soft-fail with OCSP.

This proposal is based on a generic concept of expressing a security policy within the certificate. While the OIDs for this extension and the associated policy have not been defined yet one can easily construct a certificate using this extension with PKI.js:

cert_simpl.extensions.push(new org.pkijs.simpl.EXTENSION({
    extnID: "1.2.3", // No OIDs assigned yet
    critical: false,
    extnValue: (new org.pkijs.asn1.SEQUENCE({
        value: [
                   new org.pkijs.asn1.INTEGER({ value: 4 }),
                   new org.pkijs.asn1.INTEGER({ value: 5 }),
                   new org.pkijs.asn1.INTEGER({ value: 6 })
               ]
               })).toBER(false)
}));

NOTE: In the above snip-it we just made up two OID values, hopefully IANA will assign OIDs soon so it is possible for browsers and CAs to implement this extension formally.

Why shouldn’t you use safe-deposit boxes to store Bitcoin?

Banks are not exactly what they used to be. I don’t know exactly when it changed but as a boy I remember banks being these massive buildings with large vault doors, armed guards and cameras everywhere but it seems increasingly they are located in strip malls right next to a Great Clips with nothing more an alarm and a small safe in the back. Frankly most don’t even offer safe deposit services any longer.

The lack of security of these facilities offer is not why I don’t recommend their use; it is because they can’t be trusted to keep your valuables safe. Not only can the federal government seize the contents of these safe deposit boxes at will increasingly the state governments are doing so as well as a means to shore up their own finances via their unclaimed property programs.

You can mitigate some of these risks by using techniques like Shamir Secret Sharing to split your keys up into M of N parts or by utilizing multi-signature wallets where the parts or keys are stored at different facilities reducing the likelihood of these events impacting you (which you should do regardless) but as a general rule I recommend use of private facilities instead.

Private facilities have a number of value propositions above and beyond banks, these include:

  1. Not regulated which makes it more difficult for the contents to be frozen or seized
  2. Identification is often not a requirement to open an account making targeting assets in the vault more difficult
  3. Not subject to bank holidays (for example during 9/11 banks were closed in the US)
  4. May offer:
    1. Insurance that would protect you from loss;
    2. Improved security protections and procedures;
    3. 24x7x365 access to the facility;
    4. 24x7x365 armed guards;
    5. The use of “ceremony rooms” where you can privately perform transactions.

Above these value propositions a few things to keep in mind when looking at these facilities are:

  1. Do they offer dual key control? This is when they keep one key and you keep the other. This helps mitigate the risk of your key being stolen.
  2. Did they their ceremony rooms offer you sufficient confidentiality and space to perform your transactions?
  3. Do they limit how many people can be in the vault at a given time?
  4. Is the construction of the facility done in such a way that physical compromise would be difficult?
  5. Do they have adequate camera coverage and keep the recordings long enough to be useful to identify compromise?
  6. Do they follow strict procedures or are they overly lax?
  7. Do they have any attempted thefts and if so how were they handled?
  8. Have their ever been any legal claims from their customers?
  9. What are the BBB & Yelp reports for the facility?

Regardless of which facilities you choose to store your Bitcoin assets its also important to remember the old adage of “Trust but verify” and periodically access the assets to ensure their integrity and availability.

 

Generating signed messages using CMS and PKI.js

One of the most common signature formats on the web is known as CMS SignedData, this is the signature format used in PDF files, CAdES, S/MIME and several other digital signature solutions.

As a signature it has a few notable features:

  1. Having multiple signers.
  2. Including meta-data that will be signed along with the data that is being signed.
  3. Including meta-data that is outside the scope of the signature.
  4. Signing data contained within the signature or data referenced by it.

These traits mean you can do some interesting things like implementing counter-signing in-turn enabling notarization scenarios.

Utilizing PKI.js you can now create and verify this signature format, bellow is an example of how creating one of these messages looks using this library:

// #region Put a static values 
var sample_data = new Uint8Array(sample_data);
sample_data[0] = 0x00;
sample_data[1] = 0x01;
sample_data[2] = 0x02;
sample_data[3] = 0x03;
sample_data[4] = 0x04;

cms_signed_simpl = new org.pkijs.simpl.CMS_SIGNED_DATA({
    digestAlgorithms: [
        new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: "1.3.14.3.2.26" }) // SHA-1
    ],
    encapContentInfo: new org.pkijs.simpl.cms.EncapsulatedContentInfo({
        eContentType: "1.2.840.113549.1.7.1", // "data" content type
        eContent: new org.pkijs.asn1.OCTETSTRING({ value_hex: sample_data })
    }),
    signerInfos: [
        new org.pkijs.simpl.CMS_SIGNER_INFO({
            sid: new org.pkijs.simpl.cms.IssuerAndSerialNumber({
                issuer: cert_simpl.issuer,
                serialNumber: cert_simpl.serialNumber
            }),
            digestAlgorithm: new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: "1.3.14.3.2.26" }), // SHA-1
            signatureAlgorithm: new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: "1.2.840.113549.1.1.5" }), // RSA + SHA-1
        })
    ],
    certificates: [cert_simpl]
});
// #endregion 

return cms_signed_simpl.sign(privateKey, 0);

In this sample you can see we are putting our content to be signed within the SignedData message and then signing it with RSA and SHA1, this is in-the exact same thing that is needed to implement what is called opaque signed email in S/MIME.

 

Frankencerts, new extensions and PKI.js

One of the things that we wanted you to be able to use the PKI.js libraries for is the X.509 Certificates, including those with new extensions (like testing for OCSP MUST Staple or for testing other certificate processing libraries like was done in the Frankencert paper.

Here is an example of what that might look like:

function create_cert()
{
    // #region Initial variables 
    var sequence = Promise.resolve();

    var cert_simpl = new org.pkijs.simpl.CERT();

    var publicKey;
    var privateKey;
    // #endregion 

    // #region Get a "crypto" extension 
    var crypto = org.pkijs.getCrypto();
    if(typeof crypto == "undefined")
    {
        alert("No WebCrypto extension found");

        return;
    }
    // #endregion 

    // #region Put a static values 
    cert_simpl.serialNumber = new org.pkijs.asn1.INTEGER({ value: 1 });
    cert_simpl.issuer.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({
        type: "2.222.333",
        value: new org.pkijs.asn1.PRINTABLESTRING({ value: "RU" })
    }));
    cert_simpl.issuer.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({
        type: "2.222.444",
        value: new org.pkijs.asn1.PRINTABLESTRING({ value: "Test" })
    }));
    cert_simpl.subject.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({
        type: "2.222.333",
        value: new org.pkijs.asn1.PRINTABLESTRING({ value: "RU" })
    }));
    cert_simpl.subject.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({
        type: "2.222.444",
        value: new org.pkijs.asn1.PRINTABLESTRING({ value: "Test" })
    }));
    cert_simpl.notBefore.value = new Date();
    cert_simpl.notAfter.value = new Date(2016, 01, 01);

    cert_simpl.extensions = new Array(); // Extensions are not a part of certificate by default, it's an optional array

    // #region "BasicConstraints" extension
    var basic_constr = new org.pkijs.simpl.x509.BasicConstraints({
        cA: true,
        pathLenConstraint: 3
    });

    cert_simpl.extensions.push(new org.pkijs.simpl.EXTENSION({
        extnID: "2.5.29.19",
        critical: false,
        extnValue: basic_constr.toSchema().toBER(false),
        parsedValue: basic_constr // Parsed value for well-known extensions
    }));
    // #endregion 

    // #region "KeyUsage" extension 
    var bit_array = new ArrayBuffer(1);
    var bit_view = new Uint8Array(bit_array);

    bit_view[0] = bit_view[0] | 0x02; // Key usage "cRLSign" flag
    bit_view[0] = bit_view[0] | 0x04; // Key usage "keyCertSign" flag

    var key_usage = new org.pkijs.asn1.BITSTRING({ value_hex: bit_array });

    cert_simpl.extensions.push(new org.pkijs.simpl.EXTENSION({
        extnID: "2.5.29.15",
        critical: false,
        extnValue: key_usage.toBER(false),
        parsedValue: key_usage // Parsed value for well-known extensions
    }));
    // #endregion 

    cert_simpl.signatureAlgorithm.algorithm_id = "1.2.840.113549.1.1.5"; // RSA + SHA-1
    cert_simpl.signature.algorithm_id = cert_simpl.signatureAlgorithm.algorithm_id; // Must be the same value
    // #endregion 

    // #region Create a new key pair 
    sequence = sequence.then(
        function()
        {
            return crypto.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: { name: "sha-1" } }, true, ["encrypt", "decrypt", "sign", "verify"]);
        }
    );
    // #endregion 

    // #region Store new key in an interim variables
    sequence = sequence.then(
        function(keyPair)
        {
            publicKey = keyPair.publicKey;
            privateKey = keyPair.privateKey;
        },
        function(error)
        {
            alert("Error during key generation: " + error);
        }
    );
    // #endregion 

    // #region Exporting public key into "subjectPublicKeyInfo"  
    sequence = sequence.then(
        function()
        {
            return cert_simpl.subjectPublicKeyInfo.importKey(publicKey);
         }
    );
    // #endregion 

    // #region Signing final certificate 
    sequence = sequence.then(
       function()
       {
           return cert_simpl.sign(privateKey);
       },
       function(error)
       {
           alert("Error during exporting public key: " + error);
       }
    );
    // #endregion 

    sequence = sequence.then(
        function()
        {
            alert("Good result");
        },
        function(error)
        {
            alert("Error during signing: " + error);
        }
    );

    sequence.then(
        function()
        {
            return cert_simpl.verify();
        }
    ).then(
        function(result)
        {
            alert("Verification passed: " + result);
        },
        function(error)
        {
           alert("Verification failed: " + eror);
        }
    );
}

As you can see the library is designed in such a way you are not limited to the creation of some static pre-conceived layouts of these structures, you can fairly easily construct any type of certificate (or any of the other supported message types).

At a later date (if it makes sense to do so) we may also decide to add a simple layer ontop of this that abstracts out the need to understand encoding concepts as well.

This layered approach ensures the library can be used to create real-applications without the need to hack up the underlying APIs enabling developers to avoid the need to understand low-level  ASN.1 formats in detail.

Potential projects for PKI.JS

This is a list of potential projects that would benefit from PKI.js, can you think of any others that would be interesting?

  1. Adding signing, time-stamping and verifying support to pdf.js.
  2. Creating a smime.js on email.js that provides signing, verifying, encryption, decryption of S/MIME.
  3. Creating a CAdES library for web pages.
  4. Adding signature support to web document management solutions.
  5. Adding encrypted mail support in webmail offerings.
  6. Building a usable and modern certificate based authentication solution using web markup for credential selection.
  7. Creating a rich user experience for the short-lived certificates providing temporary access via SSH and TLS.

With some changes the libraries could be used in server side projects:

  1. Creating an OCSP responder based on node.js.
  2. Creating a simple CA on node.js

WebCrypto and PKI

Like it or not here it comes — within the next few months WebCrypto will be supported in various degrees across all mainstream browsers. There are plenty of posts out there talking about the security concerns of performing cryptography in the browser so I wont go into those here.

What I wanted to talk about was now that it’s here (mostly) what can we do with it? There will be those who say you do harm by making any claims about the assurances a web application makes relating to identity and confidentiality when WebCrypto is involved. The reality though is its happening and we should think about how we enable applications to use it responsibly.

This is why I started work on PKI.JS and ASN1.JS with Yuri Strozhevsky. Now that browsers have these basic crypto primitives available to them it is possible to build web applications that are interoperable with the security services used off the web, it is also possible to build new services on the web that simply were not possible before.

Now there have been libraries that that offered ASN.1 and PKI related capabilities (for example jsRSAsign, Forge and Lapo-asn1js) but none of these were complete and none built around WebCrypto as the source of crypto.

What Yuri and I set out to do is create a set of libraries that addressed these gaps and used public test suites (when available) to ensure conformance with the associated standards, including:

  1. X.509 and CRLs– RFC 5280
  2. CMS / PKCS 7 (Signed & EnvelopedData) – RFC 5652
  3. PKCS10 – RFC 2986
  4. PKCS8 – RFC 5208
  5. OCSP – RFC 6960
  6. Time-stamping – RFC 3161

For example for ASN.1 Yuri used his freely available test suite and for path building he tested against the PKITS test suite.

This of course does not mean the libraries are 100% compliant or defect free, in-fact I can promise you they are not but where test suites were clearly available we tried to utilize them so we would end up with a highly stable and standards compliant library.

At this point the libraries work in all modern browsers but only support signing, verifying, encrypting and decrypting in the Chrome dev-channel but in theory should work on Firefox nightlies as well. Unfortunately the profile and version of WebCrypto supported by Internet Explorer is outdated enough at this point these features do not work there at all yet.

These libraries have not yet been published to their public repositories but I expect them to be within the week under an BSD style license, to give some perspective on the size of this project I expect it to be just under 20,000 lines of code when released. It’s my hope that other people take this and build upon them so that the Internet has a browser friendly way to interact with these technologies.

NOTE: While I hate disclaimers like this but these libraries have not undergone any significant review please do not consider them production ready more work is needed before that’s the case.

NOTE: It’s also worth noting that until at least two browsers release their WebCrypto implementations as final products that these libraries may stop working or not work uniformly across browsers, for example at this time the nightly Chrome builds do nor support key exports which prevents implementation of the key storage structures.

P.S I actually miss spoke earlier, we did not end up include PKCS #12 in this version but most of the base structures are supported.

The bias of experience and ignorance of youth

It was really security (well pirate and BBS’s and IRC channels) that first got me seriously into computers. It was a place where I was surrounded with brilliant people and super interesting problems to explore. It did not take long for me to discover cryptography. I remember the first time I encountered the concepts; I was working on cracking a game and the publisher actually had encrypted some of the instructions and I had to figure out what it was they had used, how it worked and how to work around it.

At that moment I was hooked. Since then nearly every professional experience I have had has been in computer security — simply put I love this stuff.

As it turns out most of the last two decades I have ended up working on authentication systems of one sort of another; these end up being interesting applications of protocol design, performance design patterns and cryptography.

The nature of these spaces also resulted in me working on operating systems and security services which in turn led me to have a strong bias against the “web developers” who I viewed largely as script kiddies with no understanding of computer science fundamentals let alone security. So much so I discouraged my son from learning many of the associated technologies because “real programmers” don’t bother with such things.

There has been an amazing shift over the last decade and even if at one point I was right for the above position I certainly would not be today. Not only have the technologies that are used to make up the web evolved to the point that they are as impressive and powerful as many of their native counterparts but many of the engineers working with them have become world-class as well.

This has led to some interesting trends the most poignant being the adoption of Javascript as a language for use outside of the browser like in Node.JS and the Tessel. This has been enabled by a competitive race to build the fastest experience on the web, which has become totally dependent on Javascript.

As a technologist I love this as it makes technology more approachable, it makes it easier for things to be rapidly be built and creates portability of skill across the layers of an engineering project.

As a security practitioner it gives me pause; those of you who know me one of my favorite sayings is “Just because you can, doesn’t mean you should” and since this approachability and increased speed of innovation has obvious and natural negative implications when securing systems I am hesitant still to embrace it fully.

I take solace in this dichotomy because of something my mom would always tell me – You’re not learning if your not falling.

As we look at the features in HTML 5 and their support of things like WebCrypto, WebSockets and (god forbid) WebGL I try to remind myself how important it is not to let our personal biases hold back innovation while holding onto the rational and caution approach of my inner security practitioner.

Bitcoin Paper Wallets and Digital Backups

The folks working on Armory have done a wonderful job thinking about many of the risks associated with Bitcoin and Paper Wallets. The have even gone as far to consider the risks of a compromised printer with a feature they call SecurePrint™.

In the Certificate Authority world when managing secrets that can not be kept within a Hardware Security Module (HSM) we go a further by using similar key management tools on Tempest hardware physically located in Faraday cage under rigorous ceremonies designed to ensure every single step performed is confidential, verified and audited.

For the individual moderate Bitcoin holdings Armory provides a robust story for managing wallet keys and producing paper wallets especially when paired with something like the PiWallet. That said since once doesn’t need to physically take your Bitcoin (they can just take a copy of it) make it their own how you store it is also important.

For valuable secrets that must be stored on paper a Certificate Authority would fold the corresponding paper in half taping each of the open ends close using tamper evident seals.

They would then place each sealed paper into their own opaque tamper evident bags keeping inventory of the bag and seal serial numbers, who was present and then storing the bags and inventory in separate secure locations.

This not only makes it possible to detect what has happened with the stored paper but protects it from water as well. Consideration is also given to what kind of paper and toner is used; for most scenarios one would use archival quality paper and high quality toner. But paper burns and toners are made of organics that can break down in heat so electronic copies are often also kept.

When it comes to those electronic records the choice of what media you use to store those values is important, as many types of media are not reliable for long-term storage. Today I would use the MDISC which effectively engraves the data into a disc that is still readable by modern DVD and BluRay players promising the disc to be readable for 1,000 years.

Even though most data being stored would already be cipher-text one never wants to rely on a single point of failure and for this reason another layer of crypto would typically be used. Commonly this is as simple as using GPG or TrueCrypt with a password to encrypt the data you are going to write to the disc in-turn managing the security of that password carefully.

At this point your down to being concerned with the physical protections your storage facilities offer and ensuring you have long term access to the hardware and software necessary to use the artifacts captured above.

Keeping long-term passwords secured

We all know that passwords should be changed regularly to reduce the value to an attacker and that they should be stored in ways that they can not be easily compromised which is why generally people are encouraged not to write passwords down.

The reality is that the human brain can only retain so much information and the less often you use something the more likely it is that you will forget it.

This is true regardless of how memorable your password happens to be.

This is especially true for passwords used in key management ceremonies. Imagine being there when the first keys were generated for the first root CA on the Internet, this is a key that will exist for decades and the implications for loosing access to this key are huge. More over the passwords involved in these ceremonies do not bellong to an individual, they belong to an organization.

For these reasons key management ceremonies use password record forms; I have attached an example form to this post for your reference.

These forms once filled out are stored securely, how securely being dependent on the security needs of the scenario. For example if the password was associated with a share in a Shamir Secret Sharing scheme (M of N set of keys) one would transport and store them securely in facilities geographically distributed under lock and an dual lock control scheme.

Periodically these stored values are retrieved and changed, as part of a process to ensure continued access to systems and keys is possible.

While not something the average person needs to deal with it is relevant to those doing paper key management for large amounts of Bitcoin, important DNSSEC keys or maybe keys embedded into some device that has been mass produced.

Protecting Bitcoin keys with hardware

One of the most important things you can do to keep your Bitcoin keys safe is to get them off of your general-purpose computer and onto a single use device that is designed to perform cryptography or Bitcoin operations.

This protects you from a number of different attacks that could result in the compromise of your keys but it does so at an expense — it makes it more difficult for you to spend your Bitcoin.

This is of course not unique to Bitcoin; in the Certificate Authority world we think of utility keys (e.g. OCSP and Time-stamping) differently than we think of the keys associated with issuing certificate authorities (the ones used to sign subscriber certificates) which we think of differently than keys associated with root certificate authorities. As such we apply different key management techniques and policies to each of them.

The same is true for your bank accounts; you keep less cash in your checking account than you do your savings. This is in part because you have a bankcard and checks tied to the checking account which makes it easier for an attacker to access your funds.

If you manage your Bitcoin holdings in a similar way by having wallets for your “spending money” and wallets for your “savings” then you make it possible to apply security measures that balance convenience and security while managing your risk. These are commonly referred to as “hot” and “cold” wallets.

Additionally those people with large cash assets limit how much they keep in each account so they stay within the liability limits that their financial institutions offer (for example $250,000 USD in the case of FDIC insured institutions).

Traditional banks do the same sort of things; for example a bank with $80,000,000 USD is required to keep $8,000,000 liquid they then use the remainder in fractional reserve banking as a working asset to fund the bank. This also has the side effect of distributing the risk the bank is exposed to by distributing that capital into many different investments each with their own risk profiles.

So how does this all translate to Bitcoin and hardware key management? For most online wallets such as Coinbase are a fine way to manage the funds you spend regularly but for your savings its advantageous to manage these keys yourself instead of being part of a much larger target like an online wallet.

That takes us to Bitcoin key management solutions; Since its introduction there have been many proposed solutions. Most of these being based on either specially hardened and dedicated computers using LiveCDs like this one built on Ubuntu and this one in Tails, these images use wallets like Armory and Electrum to in these clean-room environments to perform Bitcoin operations.

The processes used here are logically equivalent to what Certificate Authorities do with “ceremony computers” where they use specially prepared Tempest rated computers in Faraday Cages with no visibility from the outside that have isolated power (protecting against Differential Power Analysis) to generate and perform operations with sensitive keys.

During these ceremonies ridged processes and controls are used to configure the machines using known software verifying every binary is as its expected to be, auditing every action under camera with multiple people auditing the activities taking place. Also when keys are generated they are protected using secret sharing schemes such as Shamir Secret Sharing and the shares are distributed to different parties who then travel separately and move those shares to secure storage facilities that are geographically distributed.

Obviously there are lots of dials you can “tweak” to control the time / complexity tradeoff involved in the above process but for those with moderate Bitcoin holdings the above would broadly be considered too onerous to even consider.

This is where turnkey products come into play while there have been a number of promising proposals producing something that is secure, usable and affordable is no small task and most of these projects have failed to achieve sufficient market penetration to succeed.

At this time the most promising solutions that are (to varying degrees available) are PiperWallet which is an Open Source printer with embedded RasberryPi that can be used to create paper wallets, based on its claims it has thought about all the right problems (quality of random numbers, etc.)

Another solution is the Open Source PiWallet, this isn’t terribly different than the PiperWallet conceptually (through it does not make any claims about the quality of its random numbers) but it doesn’t include any input or display without an added display and keyboard.

One of the most promising offerings in this space is the Trezor this is a custom designed device designed not only to be useful for cold wallet storage but for actual personal hot wallet use as well. I am looking forward to getting a chance to use one once it becomes generally available.

On the high end of the equation one could also use a Thales nCipher or a SafeNet while these devices are not Bitcoin specific they can be used along with a ceremony computer and a modified Bitcoin wallet to secure the keys used in your wallets.

Above and beyond these solutions there are a half a dozen half-done not maintained smart card solutions (1 ,23) that have potential but unless you’re a JavaCard developer and/or Smart Card Professional these are frankly not viable options yet.