Search code examples
javascriptwebcrypto-api

PKI.js V2 and and WebCrypto - add Subject Alternative Name with CSR (Certificate Signing Request)


I have a full functional code in V1 of PKI.js and WebCrypto API that add Subject Alternative Name (DNS:) with CSR. I am trying the same with V2, but the code is not running.

Full functional example with Version 1

The V1 example with CSRhelp. This example does not add Subject Alternative Name with CSR.

Please download this zip: https://getwww.me/V1-csrhelp-master.zip In the file csrhelp-master\app\src\csrhelps\CsrhelpService.js line number 516, you’ll find the following code:

pkcs10_simpl.attributes.push(new org.pkijs.simpl.ATTRIBUTE({
                    type: "1.2.840.113549.1.9.14", // pkcs-9-at-extensionRequest
                    values: [(new org.pkijs.simpl.EXTENSIONS({
                        extensions_array: [
                            new org.pkijs.simpl.EXTENSION({
                                extnID: "2.5.29.14",
                                critical: false,
                                extnValue: (new org.pkijs.asn1.OCTETSTRING({
                                    value_hex: result
                                })).toBER(false)
                            })
                        ]
                    })).toSchema()]
                }));

I replaced the above code with the code given below, line numbers 480 to 511 (in #region SubjectKeyIdentifier). And it’s working fine.

var extensions = new org.pkijs.simpl.EXTENSIONS({
                 extensions_array: [
                    new org.pkijs.simpl.EXTENSION({
                        extnID: "2.5.29.14",
                        critical: false,
                        extnValue: (new org.pkijs.asn1.OCTETSTRING({ value_hex: result })).toBER(false)
                                })
                            ]
                        });

var altNames = new org.pkijs.simpl.GENERAL_NAMES({
        names: [
            new org.pkijs.simpl.GENERAL_NAME({
            NameType: 2,
            Name: "domain1.com, DNS:domain2.com, DNS:domain3.com"
                                           })
                                  ]
                });

        extensions.extensions_array.push(new org.pkijs.simpl.EXTENSION({
                         extnID: "2.5.29.17", // subjectAltName
                         critical: false,
                         extnValue: altNames.toSchema().toBER(false)
                     }));


        var attribute = new org.pkijs.simpl.ATTRIBUTE({
            type: "1.2.840.113549.1.9.14", // pkcs-9-at-extensionRequest
            values: [extensions.toSchema()]
                });

        pkcs10_simpl.attributes.push(attribute);

Version 2

Now I am trying the same with a V2 example PKCS#10 complex example. Please note that I taken this code directly from the pkijs.org link instead of github.

Please download this zip:https://getwww.me/V2-PKCS10_complex_example.zip In the file V2 PKCS10_complex_example/ PKCS10_complex_example.js line number 16784, you’ll find the following code:

pkcs10.attributes.push(new Attribute({
        type: "1.2.840.113549.1.9.14", // pkcs-9-at-extensionRequest
        values: [new Extensions({
        extensions: [new Extension({
        extnID: "2.5.29.14",
        critical: false,
        extnValue: new OctetString({ valueHex: result }).toBER(false)
                    })]
                }).toSchema()]
            }));

I replaced the above code (in region SubjectKeyIdentifier) with the code given below, line numbers 16749 to 16780.

var extns = new Extensions();

extns.extensions = new Array();

extns.extensions.push(new Extension({
            extnID: "2.5.29.14",
            critical: false,
            extnValue: (new OctetString({ valueHex: result })).toBER(false)
                                }));

var altNames = new GeneralNames({
        names: [
        new GeneralName({
        NameType: 2,
        Name: "domain1.com, DNS:domain2.com, DNS:domain3.com"
                                           })
                                  ]
                });

extns.extensions.push(new Extension({
        extnID: "2.5.29.17", // subjectAltName
        critical: false,
        extnValue: altNames.toSchema().toBER(false)
                     }));


var attribute = new Attribute({
        type: "1.2.840.113549.1.9.14", // pkcs-9-at-extensionRequest
        values: [extns.toSchema()]
                });

pkcs10.attributes.push(attribute);

But this is not running. I can't find out where I am doing wrong. Please help.

I have attached both V1 and V2 example (modified) as zip: links are given above.

Thanks in advance.


Solution

  • Update 2019-02-05: Alternatives (for node)

    After years of coming back to this problem I finally felt enough of the nag to create much smaller alternatives:

    They're much "dumber" in that rather than implementing the full ASN.1 and x.509 specs, they only implement the parts that are important for standard keys and standard CSRs. Hence they end up being fast, lightweight, and easy to build on.

    I've been meaning to adapt them to browser versions as well. If you bug me about it I'll get that done too. It's pretty simple (and mostly done), just tedious enough that I haven't finished the conversion.

    v2 Example

    An official example for v2 with SAN support was added today (Apr 18, 2018):

    https://github.com/PeculiarVentures/PKI.js/commit/df5ee2acaf1ffafed6cde8b974e9186d3c4cac78

    (Thank you so much for posting your v1 edit - I'm working through that now since my goal is to use regular JavaScript)

    v1.3.33 Example

    I've got a v1 example (based on your work) available at https://coolaj86.com/articles/lets-encrypt-v2-step-by-step/

    Online Demo

    Check out Greenlock™ for Web Browsers: