WIP more asn1
This commit is contained in:
parent
ba92407194
commit
ab8ec9fa7c
107
lib/ecdsacsr.js
107
lib/ecdsacsr.js
|
@ -26,21 +26,21 @@ function ASN1() {
|
|||
}
|
||||
return hex + numToHex(len) + str;
|
||||
}
|
||||
|
||||
function UINT() {
|
||||
ASN1.UInt = function UINT() {
|
||||
var str = Array.prototype.slice.call(arguments).join('');
|
||||
var first = parseInt(str.slice(0, 2), 16);
|
||||
// high-order bit means signed, negative
|
||||
// we want positive, so we pad with a leading '00'
|
||||
if (0x80 & first) { str = '00' + str; }
|
||||
return ASN1('02', str);
|
||||
}
|
||||
};
|
||||
|
||||
function BITSTR() {
|
||||
ASN1.BitStr = function BITSTR() {
|
||||
var str = Array.prototype.slice.call(arguments).join('');
|
||||
// '00' is a mask of how many bits of the next byte to ignore
|
||||
return ASN1('03', '00' + str);
|
||||
}
|
||||
};
|
||||
|
||||
function SEQ() {
|
||||
return ASN1('30', Array.prototype.slice.call(arguments).join(''));
|
||||
}
|
||||
|
@ -204,22 +204,27 @@ function csrEcSig(r, s) {
|
|||
// (ANSI X9.62 ECDSA algorithm with SHA256)
|
||||
OBJID('2A 86 48 CE 3D 04 03 02')
|
||||
)
|
||||
, BITSTR(
|
||||
, ASN1.BitStr(
|
||||
SEQ(
|
||||
UINT(toHex(r))
|
||||
, UINT(toHex(s))
|
||||
ASN1.UInt(toHex(r))
|
||||
, ASN1.UInt(toHex(s))
|
||||
)
|
||||
)
|
||||
].join('');
|
||||
}
|
||||
var csrDomains = '82 {dlen} {domain.tld}'; // 2+n bytes (type 82?)
|
||||
|
||||
// TODO utf8
|
||||
function strToHex(str) {
|
||||
return str.split('').map(function (ch) {
|
||||
var h = ch.charCodeAt(0).toString(16);
|
||||
if (2 === h.length) {
|
||||
return h;
|
||||
}
|
||||
var escstr = encodeURIComponent(str);
|
||||
// replaces any uri escape sequence, such as %0A,
|
||||
// with binary escape, such as 0x0A
|
||||
var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
});
|
||||
return binstr.split('').map(function (b) {
|
||||
var h = b.charCodeAt(0).toString(16);
|
||||
if (2 === h.length) { return h; }
|
||||
return '0' + h;
|
||||
}).join('');
|
||||
}
|
||||
|
@ -249,7 +254,7 @@ function fromHex(hex) {
|
|||
|
||||
function createCsrBodyEc(domains, xy) {
|
||||
var altnames = domains.map(function (d) {
|
||||
return csrDomains.replace(/{dlen}/, numToHex(d.length)).replace(/{domain\.tld}/, strToHex(d));
|
||||
return ASN1('82', strToHex(d));
|
||||
}).join('').replace(/\s+/g, '');
|
||||
var sublen = domains[0].length;
|
||||
var sanlen = (altnames.length/2);
|
||||
|
@ -272,56 +277,54 @@ function createCsrBodyEc(domains, xy) {
|
|||
hxy += toHex(xy.y);
|
||||
}
|
||||
|
||||
var version = ASN1.UInt('00');
|
||||
var subject = ASN1('30'
|
||||
, ASN1('31'
|
||||
, ASN1('30'
|
||||
// object id (commonName)
|
||||
, ASN1('06', '55 04 03')
|
||||
, ASN1('0C', strToHex(domains[0])))));
|
||||
var pubkey = ASN1('30'
|
||||
, ASN1('30'
|
||||
// 1.2.840.10045.2.1 ecPublicKey
|
||||
// (ANSI X9.62 public key type)
|
||||
, ASN1('06', '2A 86 48 CE 3D 02 01')
|
||||
// 1.2.840.10045.3.1.7 prime256v1
|
||||
// (ANSI X9.62 named elliptic curve)
|
||||
, ASN1('06', '2A 86 48 CE 3D 03 01 07')
|
||||
)
|
||||
, ASN1.BitStr(compression + hxy));
|
||||
var altnames = ASN1('A0'
|
||||
, ASN1('30'
|
||||
// (extensionRequest (PKCS #9 via CRMF))
|
||||
, ASN1('06', '2A 86 48 86 F7 0D 01 09 0E')
|
||||
, ASN1('31'
|
||||
, ASN1('30'
|
||||
, ASN1('30'
|
||||
// (subjectAltName (X.509 extension))
|
||||
, ASN1('06', '55 1D 11')
|
||||
, ASN1('04'
|
||||
, ASN1('30', domains.map(function (d) {
|
||||
return csrDomains.replace(/{dlen}/, numToHex(d.length)).replace(/{domain\.tld}/, strToHex(d));
|
||||
}).join(''))))))));
|
||||
var body = [ '30 81 {+85+n}' // 4 bytes, sequence
|
||||
.replace(/{[^}]+}/, numToHex(
|
||||
3
|
||||
+ 13 + sublen
|
||||
+ 27 + publen // Length for EC-related P-256 stuff
|
||||
+ 30 + sanlen
|
||||
))
|
||||
.replace(/{[^}]+}/, numToHex(3 + 13 + sublen + 27 + publen + 30 + sanlen))
|
||||
|
||||
// #0 Total 3
|
||||
, ASN1('02', '00')
|
||||
, version
|
||||
|
||||
// Subject
|
||||
// #1 Total 2+11+n
|
||||
, ASN1('30'
|
||||
, ASN1('31'
|
||||
, ASN1('30'
|
||||
// object id (commonName)
|
||||
, ASN1('06', '55 04 03')
|
||||
, ASN1('0C', strToHex(domains[0]))
|
||||
)
|
||||
)
|
||||
)
|
||||
, subject
|
||||
|
||||
// P-256 Public Key
|
||||
// #2 Total 2+25+xy
|
||||
, ASN1('30'
|
||||
, ASN1('30'
|
||||
// 1.2.840.10045.2.1 ecPublicKey
|
||||
// (ANSI X9.62 public key type)
|
||||
, ASN1('06', '2A 86 48 CE 3D 02 01')
|
||||
// 1.2.840.10045.3.1.7 prime256v1
|
||||
// (ANSI X9.62 named elliptic curve)
|
||||
, ASN1('06', '2A 86 48 CE 3D 03 01 07')
|
||||
)
|
||||
, BITSTR(compression + hxy)
|
||||
)
|
||||
, pubkey
|
||||
|
||||
// Altnames
|
||||
// #3 Total 2+28+n
|
||||
, ASN1('A0'
|
||||
, ASN1('30'
|
||||
// (extensionRequest (PKCS #9 via CRMF))
|
||||
, ASN1('06', '2A 86 48 86 F7 0D 01 09 0E')
|
||||
, ASN1('31'
|
||||
, ASN1('30'
|
||||
, ASN1('30'
|
||||
// (subjectAltName (X.509 extension))
|
||||
, ASN1('06', '55 1D 11')
|
||||
, ASN1('04'
|
||||
, ASN1('30', altnames))))))) ];
|
||||
, altnames
|
||||
];
|
||||
body = body.join('').replace(/\s+/g, '');
|
||||
return fromHex(body);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue