-
-
Save lapo-luchini/5d770e91dee2b258fd006fbf6ed38ffc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const | |
asn1 = require('asn1.js'), | |
rfc5280 = require('asn1.js-rfc5280'), | |
Version = asn1.define('Version', function () { | |
this.int({ | |
1: 'v1', | |
}); | |
}), | |
MessageImprint = asn1.define('MessageImprint', function () { | |
this.seq().obj( | |
this.key('hashAlgorithm').use(rfc5280.AlgorithmIdentifier), | |
this.key('hashedMessage').octstr() | |
); | |
}), | |
TimeStampReq = asn1.define('TimeStampReq', function () { | |
this.seq().obj( | |
this.key('version').use(Version), | |
this.key('messageImprint').use(MessageImprint), | |
this.key('reqPolicy').objid().optional(), | |
this.key('nonce').int().optional(), | |
this.key('certReq').bool().optional() | |
//this.key('extensions').use(Extensions).optional(), // not supported at this time | |
); | |
}), | |
PKIStatusInfo = asn1.define('PKIStatusInfo', function () { | |
this.seq().obj( | |
this.key('status').int({ | |
0: 'granted', // when the PKIStatus contains the value zero a TimeStampToken, as requested, is present | |
1: 'grantedWithMods', // when the PKIStatus contains the value one a TimeStampToken, with modifications, is present | |
2: 'rejection', | |
3: 'waiting', | |
4: 'revocationWarning', // this message contains a warning that a revocation is imminent | |
5: 'revocationNotification', // notification that a revocation has occurred | |
}), | |
this.key('statusString').optional().seqof(this.utf8str()), // PKIFreeText as defined in RFC4210 | |
this.key('failInfo').optional().bitstr({ | |
'0': 'badAlg', | |
'2': 'badRequest', | |
'5': 'badDataFormat', | |
'14': 'timeNotAvailable', | |
'15': 'unacceptedPolicy', | |
'16': 'unacceptedExtension', | |
'17': 'addInfoNotAvailable', | |
'25': 'systemFailure' | |
}) | |
); | |
}), | |
CertificateChoices = asn1.define('CertificateChoices', function () { | |
this.choice({ | |
certificate: this.use(rfc5280.Certificate), | |
extendedCertificate: this.implicit(0).use(rfc5280.Certificate), | |
v1AttrCert: this.implicit(1).use(rfc5280.Certificate), | |
v2AttrCert: this.implicit(2).use(rfc5280.Certificate), | |
other: this.implicit(3).seq().obj( | |
this.key('otherCertFormat').objid(), | |
this.key('otherCert').any() | |
) | |
}); | |
}), | |
RevocationInfoChoice = asn1.define('RevocationInfoChoice', function () { | |
this.choice({ | |
crl: this.use(rfc5280.CertificateList), | |
other: this.implicit(1).seq().obj( | |
this.key('otherRevInfoFormat').objid(), | |
this.key('otherRevInfo').any() | |
) | |
}); | |
}), | |
SignerInfo = asn1.define('SignerInfo', function () { | |
this.seq().obj( | |
this.key('version').int(), | |
this.key('sid').choice({ | |
issuerAndSerialNumber: this.seq().obj( | |
this.key('issuer').use(rfc5280.Name), | |
this.key('serialNumber').use(rfc5280.CertificateSerialNumber) | |
) | |
}), | |
this.key('digestAlgorithm').use(rfc5280.AlgorithmIdentifier), | |
this.key('signedAttrs').optional().implicit(0).setof(common.Attribute), | |
this.key('signatureAlgorithm').use(rfc5280.AlgorithmIdentifier), | |
this.key('signature').octstr(), | |
this.key('unsignedAttrs').optional().implicit(1).setof(common.Attribute) | |
); | |
}), | |
SignedData = asn1.define('SignedData', function () { | |
this.seq().obj( | |
this.key('version').int(), | |
this.key('digestAlgorithms').setof(rfc5280.AlgorithmIdentifier), | |
this.key('encapContentInfo').seq().obj( | |
this.key('eContentType').objid(), | |
this.key('eContent').optional().explicit(0).octstr(),//.contains(TSTInfo), | |
), | |
this.key('certificates').optional().implicit(0).setof(CertificateChoices), | |
this.key('crls').optional().implicit(1).setof(RevocationInfoChoice), | |
this.key('signerInfos').setof(SignerInfo) | |
) | |
}), | |
TimeStampToken = asn1.define('TimeStampToken', function () { | |
this.seq().obj( | |
this.key('contentType').objid(), | |
this.key('content').optional().explicit(0).use(SignedData) | |
); | |
}), | |
TimeStampResp = asn1.define('TimeStampResp', function () { | |
this.seq().obj( | |
this.key('status').use(PKIStatusInfo), | |
this.key('timeStampToken').optional().use(TimeStampToken) // would be use(TimeStampToken), but not decoded at this time | |
); | |
}), | |
TSTInfo = asn1.define('TSTInfo', function () { | |
this.seq().obj( | |
this.key('version').use(Version), | |
this.key('policy').objid(), | |
this.key('messageImprint').use(MessageImprint), // MUST have the same value as the similar field in TimeStampReq | |
this.key('serialNumber').int(), // Time-Stamping users MUST be ready to accommodate integers up to 160 bits. | |
this.key('genTime').gentime(), | |
this.key('accuracy').optional().any(), //TODO Accuracy | |
this.key('ordering').bool().def(false), | |
this.key('nonce').optional().int(), // MUST be present if the similar field was present in TimeStampReq. In that case it MUST have the same value. | |
// tsa [0] GeneralName OPTIONAL | |
// extensions [1] IMPLICIT Extensions OPTIONAL | |
); | |
}), | |
str = '308206a030030201003082069706092a864886f70d010702a08206883080020103310f300d060960864801650304020105003080060b2a864886f70d0109100104a0802480046a306802010106032a0304302f300b06096086480165030402010420780c8c51ea21b68bca74ae30ab802b458955ad56f6152b23d2daacb34b62bf00021500b77d8590c5dcc1143351b2866b32cfb5518c3581181332303137303831383136313031352e3830385a0101ff000000000000a0803082039e30820286a003020102020458761652300d06092a864886f70d0101020500303a310b3009060355040613024954310f300d060355040a0c06416e64786f72311a301806035504030c11416e64786f7220506f7274616c20545341301e170d3137303131313131323933315a170d3237303131313131323933315a303a310b3009060355040613024954310f300d060355040a0c06416e64786f72311a301806035504030c11416e64786f7220506f7274616c2054534130820122300d06092a864886f70d01010105000382010f003082010a02820101008e6f17600b485a3d3bc5272657d117785642e66abd50187d04639b0fac85f2e0d345b379c28a2a123ff1fcefaa159ce350685bd8f7434ec880b19d64e4b01be34c725ed22eac98306851cb9b9889b80f16ef821b1a5b572085c14c5dc5a14afbdcccfba643c4d44e69df9ce462c8d659e3f523117767379860a9039529347a5e7e6d29728819104a067d89eeb0580db1d2fbc5199ebd69afb0e3eea60e6cd9f6337d6e47c3c1d0442cc4db8c63babfa4d13c8356fc3fb7a28b3e7eca3d15fb29408f97ab883533b7c0d6220e1c33d81f09dfd7f0ad9884f3a2958806cf917fb86ed794220ccc5043bce062175ab2dd2144d6546a11092a138eea1f9e9def4b4f0203010001a381ab3081a830650603551d23045e305c8014b7552cf03ab7fd784c212cb6d47adc315d4e7d74a13ea43c303a310b3009060355040613024954310f300d060355040a1306416e64786f72311a301806035504031311416e64786f7220506f7274616c20545341820458761652301d0603551d0e04160414b7552cf03ab7fd784c212cb6d47adc315d4e7d74300b0603551d0f0404030204f030130603551d25040c300a06082b06010505070308300d06092a864886f70d0101020500038201010014908064e38c6b1f6dcc0b586f9d838c1c2561f8a4e4b6abf5b44fb0cb0f30a4de52095ae4f2782822cbb8768b942b017903539c8ea69b1eb729c0c29f0aa2ccd477af51116ac846f3e1a88c9e4fc97bc01f9ae7eda95afdf0f5641aaf5e805ee4f4930d4a2a5e77518d9046df9456a2dc7376d71ad30378743f077576ee3255ff2eb96eaa4d7485d702915130080ef108d1044d98378ee13666ddd7cc9b4ba505b0c4ef88c3bd46f313d991a9ebd14ebd2acfd6c6ac83e9ff173e5ff29dfd9026ee2c8f964d53250db4392273d421c5fbcf4c4f2c5d6a2792e81aa0d07ddd457e7d4fd9f57644609647f56b07d5ed8b56e697bfbedea454f3dab9ab1f52f44c0000318202413082023d0201013042303a310b3009060355040613024954310f300d060355040a0c06416e64786f72311a301806035504030c11416e64786f7220506f7274616c20545341020458761652300d06096086480165030402010500a081d1301a06092a864886f70d010903310d060b2a864886f70d0109100104301c06092a864886f70d010905310f170d3137303831383136313031355a302b060b2a864886f70d010910020c311c301a301830160414ee6f53b5b1d9f1323009f378922b9201a3547e6a302f06092a864886f70d01090431220420f572705055d9cbe88cff0127b62819eec1b4f761d772f0d468df022e2cd2f0753037060b2a864886f70d010910022f3128302630243022042072d8d3d7d67c25597d184dafb5fdd9792f512c1275a4993c91efa1db98bd9441300d06092a864886f70d01010105000482010062b0949525ecc2d5b097f4ffdbb7107a7814a57fd6306f3b70337a2b93206fd28c809ea65e3150a4f2fcca7e2a5523f2617226f4ad2d0eed71a02f8b2c6c0837e538f0a2a21200a749d8dfc1141d4773eb261e31d016e0fa6c5c96b59bcad0d0364bd12f25656b3083c18433eca3889ad21227455a3ec55b28a8b30bbdb38c0ed842d4b6695316faddb6903bb1deccc0ade2e7ebb55d1e65ddf2c050d2cf0c3788f4d8fb4da02d3d3dd6e661169a3e94718605586d29199d5d2fa954d3147ffc34434d0b44a0395f309a69fe1e0f8995d6d020ad89ed026aea364a548d62393a093a8ba40c5a40ae308c1edaf64f127984e352565fbcff9f3807f088e958a0a40000'; | |
console.log(TimeStampResp.decode(Buffer.from(str, 'hex'))); | |
console.log(TimeStampResp.decode(Buffer.from(str, 'hex'), 'der', { | |
partial: 1, | |
track: function (path, start, end, type) { | |
console.log([ type, path, start, end ]); | |
} | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment