indutny / asn1.js Goto Github PK
View Code? Open in Web Editor NEWASN.1 Decoder/Encoder/DSL
License: MIT License
ASN.1 Decoder/Encoder/DSL
License: MIT License
EncodeBuffer constructor relies on constructor function name which can be mangled when source code is minified.
here it is: https://github.com/indutny/asn1.js/blob/master/lib/asn1/base/buffer.js#L69
can be fixed by using instance of instead.
Decoding a cert with asn1.js-rfc3280 to extract subjectPublicKeyInfo
field shows that AlgorithmIdentifier.parameters
was missed, where 0x05,0x00(NULL) was set in the case of RSA. The field was parsed in the next subjectPublicKey
field in the unused
property.
{ algorithm: { algorithm: [ 1, 2, 840, 113549, 1, 1, 1 ] },
subjectPublicKey:
{ unused: 0,
data: <Buffer 30 82 01 0a 02 82 01 01 00 b7 89 4e 02 f9 ba 01 e0 78 89 d6 70 fd 36 18 d6 02 2e fc 96 c9 d9 de ae 2e 80 0a a1 9f 4b 17 20 c3 71 b9 99 6b 2e fc 12 fa ... > } }
It seems that the decoder cannot parse and obtain the field with defined with optional().any()
.
This causes the problem when we want to extract the der data of subjectPublicKey
from tbsCertificate
by simply decoding and encoiding of cert.tbsCertificate.subjectPublicKeyInfo
with
var spki_der = SubjectPublicKeyInfo.encode(cert.tbsCertificate.subjectPublicKeyInfo, 'der');
so that NULL(0x05,0x00) was missed.
But we have a workaround to set the value of parameters explicitly.
var spki = cert.tbsCertificate.subjectPublicKeyInfo;
var new_spki = {algorithm : {algorithm: spki.algorithm.algorithm, parameters: new Buffer('0500', 'hex')},
subjectPublicKey: {data: spki.subjectPublicKey.data}};
var spki_der = SubjectPublicKeyInfo.encode(new_spki, 'der');
If there is a more simple way to extract the der data, please let me know it.
When seqof()
is used with optional()
the decoded results are not parsed or included in the resulting object. PR #61 updates _peekTag() to check for seqof/setof when optional. The added tests highlight the issue.
NPM registry is apparently missing the tarball for this version:
https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.0.tgz replies:
{
error: "package could not be found."
}
Getting this error when npm installing browserify 8.0.3:
npm ERR! peerinvalid The package asn1.js does not satisfy its siblings' peerDependencies requirements!
I have found that too:
npm ERR! peerinvalid Peer [email protected] wants asn1.js@^0.6.0
The problem comes from browserify-sign
that references asn1.js-rfc3280
I guess.
Updating the package.json
peerDependencies object in the rfc 3280 from "asn1.js": "^0.6.0"
too 0.6.6
or 0.6.x
could resolve that ?
If it is the solution, it probably has to be done in the rfc 2560 too.
PR #59 adds support for encapsulated models in bit strings or octet strings.
Examples can be found in RFC 5280:
Extension ::= SEQUENCE {
-- ...
extnValue OCTET STRING
-- contains the DER encoding of an ASN.1 value
-- corresponding to the extension type identified
-- by extnID
}
or in RFC 5912 where it is explicitly used:
Extension{EXTENSION:ExtensionSet} ::= SEQUENCE {
-- ...
extnValue OCTET STRING (CONTAINING
EXTENSION.&ExtnType({ExtensionSet}{@extnID}))
-- contains the DER encoding of the ASN.1 value
-- corresponding to the extension type identified
-- by extnID
}
Hello,
Have you had any reports of issues when using asn1.js library in conjunction with Microsoft Edge browser? (and yes, I realize you do not have access to any Windows machines!)
regards,
Greg
Explicit fields should be prefixed with 0xA0 | TAG byte, but instead are coded as 0x20 | TAG.
Following test-case shows invalid encoding:
var asn1 = require('asn1.js');
var Bug = asn1.define('Bug', function() {
this.explicit(2).octstr()
});
var encoded = Bug.encode("X", 'der');
console.log(encoded);
// output: <Buffer 22 03 04 01 58>
Correct output for this particular scheme should be A2 03 04 01 58
Should support unbound integers somehow.
Hi, I have a problem when decoding a TimeStampResp… when using normal decode only status
is printed, while the answer is complete and certainly contains more, when using partial: true
it enters a loop and never stops.
I wasn't able to detect the loop using the inspector so far (nor find any problem in my ASN.1 definition).
I saved my self-contained test case in this gist.
{ status: { status: 'granted' } }
[ 'tagged', '', 0, 1700 ]
[ 'content', '', 4, 1700 ]
[ 'tagged', 'status', 4, 9 ]
[ 'content', 'status', 6, 9 ]
[ 'tagged', 'status/status', 6, 9 ]
[ 'content', 'status/status', 8, 9 ]
[ 'tagged', 'timeStampToken', 9, 1700 ]
[ 'content', 'timeStampToken', 13, 1700 ]
[ 'tagged', 'timeStampToken/contentType', 13, 24 ]
[ 'content', 'timeStampToken/contentType', 15, 24 ]
[ 'tagged', 'timeStampToken/content', 28, 183 ]
[ 'content', 'timeStampToken/content', 30, 183 ]
[ 'tagged', 'timeStampToken/content/version', 30, 33 ]
[ 'content', 'timeStampToken/content/version', 32, 33 ]
[ 'tagged', 'timeStampToken/content/digestAlgorithms', 33, 50 ]
[ 'content', 'timeStampToken/content/digestAlgorithms', 35, 50 ]
^C
ASN.1 states:
if the value of a component with the OPTIONAL or DEFAULT qualifier is absent from the sequence, then the encoding of that component is not included in the contents octets
This line:
Line 4 in 0abb73e
Is affecting other projects when using browserify, see:
https://github.com/bitpay/copay/issues/7001
Hello,
I do not know your codebase enough to know what would be the correct returned value.
https://github.com/indutny/asn1.js/blob/master/lib/asn1/base/node.js#L367
Thanks.
Hi!
Version 4.10 broke our build because it's being used in a browserify/webpack shim for node's crypto library. Uglify caught this for us as it started choking on const
.
cc: @ljharb @goatslacker
Here is the dep tree:
~/airlab/repos/thinger master*
└─┬ [email protected]
└─┬ [email protected]
└─┬ [email protected]
└─┬ [email protected]
└─┬ [email protected]
└── [email protected]
The following code returns undefined:
rfc3280.AttributeType.decode(new Buffer('06092A864886F70D010903','hex'), 'der');
As a result, while decoding an object that uses unknown objid, we see a corresponding key missing.
I think, an error should be thrown or objid should be written as a numeric string.
Encoding seems to work, decoding does not work. A test case is here felix@ea45c61
When trying to install bower (which uses parse-asn1, and transitively, asn1.js), the install tries to pull in asn1.js 4.10.0, which doesn't exist. There's a GitHub release, but no yarn version, apparently. Forcing 4.9.2 does work.
The error I'm getting is:
yarn install v1.2.1
[1/4] Resolving packages...
[2/4] Fetching packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.0.tgz: Request failed \"404 Not Found\"".
info If you think this is a bug, please open a bug report with the information provided in "/jenkins/workspace/rs_aa-web-tng_jenkins_build-PDLIB2YYFPZ3HKD27EE26S7JKYWCT2YIOP46OX7JC4W7ITGSUOKA/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
script returned exit code 1
If you install asn1.js without the optional dependencies (--no-optional), the bn.js dependency isn't installed but then asn1.js fails to work because it expects it to exist in https://github.com/indutny/asn1.js/blob/master/lib/asn1.js#L3. Either treat is optional or mark it as required.
Following syntax does not work when translated to asn1.js DSL:
B :: = SEQUENCE {
x OCTET STRING }
A ::= SEQUENCE {
b [0] IMPLICIT B }
When child model is defined via this.use(Child)
, it ignores implicit tag from parent model.
Test case: https://gist.github.com/muromec/fa3d896be964bb1a9f4c
The choice tag is decoded just fine: Vanuan@8deaa9c#diff-93bb5384f2f7698560a5cd4fe592b374R55
But when I try to encode it: Vanuan@8deaa9c#diff-f622ac5d468e8670f218b180970d8552R32
It fails with:
Error: Child should have a key at: (shallow)
at Reporter.error (asn1.js/lib/asn1/base/reporter.js:53:11)
at DERNode.<anonymous> (asn1.js/lib/asn1/base/node.js:463:25)
at Array.map (native)
at DERNode.encode [as _encode] (asn1.js/lib/asn1/base/node.js:461:30)
at DERNode.encode [as _encode] (asn1.js/lib/asn1/base/node.js:435:30)
at Model.encode (asn1.js/lib/asn1/encoders/der.js:23:20)
There are parts of ASN.1 definition which content depends on the object identifier.
For example, to encode/decode PKCS7 ContentInfo we need 2 steps:
ContentInfo ::= SEQUENCE {
contentType ContentType,
content
[0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
Is there a way to define ASN.1 js model to do that in one step? I.e. some kind of conditional typing/objid mapping, maybe...
The same problem goes with AlgorithmIdentifier.
The deficiency of ping-pong testing approach is that it only tests encode-decode path.
The decode-encode path is not tested, unfortunately.
'use strict';
const rfc5280 = require('./rfc/5280');
const tbs =
I guess this file doesn't need to be included in distributed npm package or should be valid JS file
I am using Create React App and on 'npm run build' getting the following error -
Failed to minify the code from this file:
./node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/decoders/der.js:58
Read more here: http://bit.ly/2tRViJ9
There is a typo in the RFC 5280 API.
CerficateList
should be CertificateList
instead.
370:d=5 hl=2 l= 3 prim: OBJECT :X509v3 CRL Distribution Points
375:d=5 hl=2 l= 48 prim: OCTET STRING [HEX DUMP]:302E302CA02AA028862668747470733A2F2F6C6F63616C686F73743A383838382F726F6F742D63612F63726C2E70656D
Pulled off a cert.
I can't find a good way to parse the octet string above, it should look like :
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
DistributionPoint ::= SEQUENCE {
distributionPoint [0] DistributionPointName OPTIONAL,
reasons [1] ReasonFlags OPTIONAL,
cRLIssuer [2] GeneralNames OPTIONAL }
DistributionPointName ::= CHOICE {
fullName [0] GeneralNames,
nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
ReasonFlags ::= BIT STRING {
unused (0),
keyCompromise (1),
cACompromise (2),
affiliationChanged (3),
superseded (4),
cessationOfOperation (5),
certificateHold (6),
privilegeWithdrawn (7),
aACompromise (8) }
But notice that in the hex dump there is no explicit tag for CHOICE
. Been fiddling but unable to find a workaround easily.
Installing this specific version from npm return an error that it does not exist.
Character string types support would be great
http://www.obj-sys.com/asn1tutorial/node128.html
result
is never defined: https://github.com/indutny/asn1.js/blob/v4.2.1/lib/asn1/decoders/der.js#L185-L193
In the browser (asn1.js is used [eventually through dependencies] by crypto-browserify) this is causing issues.
Not sure if it was intentionally not defined or not. It was in the initial commit and I find it difficult to believe it has not come up before.
The following snippet yields 63744
:
var asn = require('asn1.js');
var Human = asn.define('Human', function() {
this.seq().obj(
this.key('firstName').int(),
);
});
var output = Human.encode({
firstName: 2500000000,
}, 'der');
var human = Human.decode(output, 'der');
console.log(human.firstName.toNumber());
It seems like an integer overflow. Shouldn't it allow more than 32 bits?
It'd be nice to be able to use the PEM format in addition to DER.
Conversion from PEM to DER should be quite simple, I even wrote a quick DER-to-PEM function:
var base64 = require('base64-js'),
convertHex = require('convert-hex');
var derToPem = function(derPrivateKey) {
var byteArrayPrivateKey = convertHex.hexToBytes(derPrivateKey);
var base64PrivateKey = base64.fromByteArray(byteArrayPrivateKey);
var pemBeginning = '-----BEGIN PRIVATE KEY-----';
var pemEnding = '-----END PRIVATE KEY-----';
var pemMiddle = base64PrivateKey.match(/.{1,64}/g).join('\n');
var pemPrivateKey = [pemBeginning, pemMiddle, pemEnding].join('\n');
return pemPrivateKey;
};
Let me know what you think, thanks!
Either option is trivial to implement but this would save a lot of time when an encoding is not explicitly specified. Since BER is not implemented and PEM is not as popular then DER would be a good default. But it is probably better to just throw an error. ATM it just complains about something else being 'undefined', not particularly helpful.
Give a preference and I will make a PR.
Since I got the latest version, my webpack build now fails.
Unexpected token: name (len) [./~/asn1.js/lib/asn1/decoders/der.js:58,0][vendor.js:93723,6]
in undefined
My dependency tree is
`-- [email protected]
`-- [email protected]
`-- [email protected]
`-- [email protected]
`-- [email protected]
`-- [email protected]
When installing asn1.js with npm install asn1.js
I noticed that unless I set the version to 4.8.0 the rfc directory is not included under node_modules/asn1.js and I can't parse X.509 certificates. Is this a packaging bug or is it intentional and if so, what is the recommended way to decode a certificate with the latest version?
This fails
it ('BigNum bug in ASN.1 implementation', () => {
var ASNInteger = asn1.define('Integer', function () {
this.seq().obj(
this.key('aNumber').int());
});
var serialized = ASNInteger.encode({aNumber: 2}, 'der');
var two = ASNInteger.decode(serialized, 'der');
assert.equal(two.aNumber, 2);
assert.equal(two+1, 3); // Fail
});
With
AssertionError: expected '[object Object]1' to equal 3
Expected :3
Actual :"[object Object]1"
It turns out that the example in the readme isn't quite correct:
it ('example from github', () => {
var Human = asn1.define('Human', function() {
this.seq().obj(
this.key('firstName').octstr(),
this.key('lastName').octstr(),
this.key('age').int(),
this.key('gender').enum({ 0: 'male', 1: 'female' }),
this.key('bio').seqof(Bio)
);
});
var Bio = asn1.define('Bio', function() {
this.seq().obj(
this.key('time').gentime(),
this.key('description').octstr()
);
});
var output = Human.encode({
firstName: 'Thomas',
lastName: 'Anderson',
age: 28,
gender: 'male',
bio: [
{
time: +new Date('31 March 1999'),
description: 'freedom of mind'
}
]
}, 'der');
var human = Human.decode(output, 'der');
console.log(human);
});
Prints
{ firstName: <Buffer 54 68 6f 6d 61 73>,
lastName: <Buffer 41 6e 64 65 72 73 6f 6e>,
age: <BN: 1c>,
gender: 'male',
bio:
[ { time: 922831200000,
description: <Buffer 66 72 65 65 64 6f 6d 20 6f 66 20 6d 69 6e 64> } ] }
I expect age to be 28
but it's <BN: 1c>
, which seems to be a BigNum. How is it supposed to work? According to the readme or according to this test case?
Thanks
Hi,
I'm running into an issue with a package that uses your module. I'm able to install v4.0.0 fine, but when I try to install the recently released 4.0.1, I receive
npm ERR! node v4.2.2
npm ERR! npm v2.15.1
npm ERR! code ETARGET
npm ERR! notarget No compatible version found: asn1.js-rfc5280@'>=4.4.0 <5.0.0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["1.0.0","1.0.1","1.0.2","1.0.3","1.2.1"]
npm ERR! notarget
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget
npm ERR! notarget It was specified as a dependency of 'asn1.js-rfc2560'
Looks like the new package.json has an invalid dependency
"asn1.js-rfc5280": "^4.4.0"
var data = new Buffer(der, 'hex');
var c = Certificate.decode(data, 'der');
var tbs = rfc3280.TBSCertificate.encode(c.tbsCertificate, 'der');
Will throw:
Error: Child should have a key at: ["issuer"]
Am I doing something wrong here? Is there any easier way to just get the raw buffer for the TBS Cert?
any plans for bmpstr
support?
Details about revoked certificates are not being properly decoded using the RFC 5280 API. No matter the contents of a CRL, the result always contains revokedCertificates: {}
.
I'm looking at implementing RFC 3161 (Time-Stamp Protocol) but need some guidance on defining this type:
PKIStatus ::= INTEGER {
granted (0),
grantedWithMods (1),
rejection (2),
waiting (3),
revocationWarning (4),
revocationNotification (5) }
Is there a mechanism in asn1.js for defining an INTEGER type with identifiers as specified for this PKIStatus type?
BER decoder and encoder needs to be implemented.
/cc @mcavage
Hey man, seen you work in https://github.com/mcavage/node-asn1. Please let me know if it may sound as an interesting idea for you, there're currently no npm module that does both BER and DER.
There's this base
file which contains a hidden cyclical dependency.
The problem is buffer
depends on base
while base
depends on buffer
.
asn1.js/lib/asn1/base/index.js
Lines 1 to 8 in bbf14e0
https://github.com/indutny/asn1.js/blob/master/lib/asn1/base/buffer.js#L4
It works in node (and probably in webpack), but it causes problems when deployed using https://unpkg.com
X.690 (08/2015), section 11 (Restrictions on BER employed by both CER and DER), subsection 11.6 (Set-of components) reads:
The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared
as octet strings with the shorter components being padded at their trailing end with 0-octets.NOTE – The padding octets are for comparison purposes only and do not appear in the encodings.
This library does not currently sort set-of components in canonical order when encoding DER.
vm-browserify
uses eval
which is disabled in Chrome Apps (completely) and Extensions (by default CSP), therefore browserified asn1.js
doesn't work.
https://developer.chrome.com/extensions/sandboxingEval
https://developer.chrome.com/apps/contentSecurityPolicy
Add support for real numbers.
Hi
version 4.10.0 of the package is missing in yarn yarnpkg/yarn#4821
There is a bug in optional handling. See test case:
Result:
I have a browserify project which depends on Mathjs(which depends on decimal.js). My app works correctly on every browser, but not on safari. It turned out that the cause is an error with the strict mode:
SyntaxError: Cannot declare a parameter named 'k' in strict mode
After looking inside the minification process, and inside the browserify generated code, I found that the code which generate the error is this one
https://github.com/indutny/asn1.js/blob/master/lib/asn1/base/node.js#L225
It is a known bug of safari implementation of strict mode. A function cannot have a parameter with the same name, the key() function in asn1/base/node module.
see the discussion here mishoo/UglifyJS#179
Module test is named rfc3280, but in fact contains only OCSP stuff.
When using implicit seqof(Type)
, where Type
is seq()
, the sequence is encoded as a0
, while it seems it should be encoded as 30
Here's a test: Vanuan/asn1.js@055b737
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.