PeculiarVentures / PKI.js

PKI.js is a pure JavaScript library implementing the formats that are used in PKI applications (signing, encryption, certificate requests, OCSP and TSP requests/responses). It is built on WebCrypto (Web Cryptography API) and requires no plug-ins.
http://pkijs.org
Other
1.3k stars 204 forks source link

Can't read data from extensions - ArrayBuffer #306

Closed ghost closed 3 years ago

ghost commented 3 years ago

Decoding a BER, can get information from each object. Some of the information can be easily obtained. But in some extensions, the data is in an unknown encoding. After a long and without results search for information on the correct conversion of the buffer to a string, unfortunately I had no choice but to ask you for help. I've used 'pvutils' and other ways to get the data, but I always get an unreadable result. For example when reading extensions: '1.2.643.100.112': bufferToHexCodes (_exts.extnValue.valueBlock.valueHex) arrayBufferToString (_exts.extnValue.valueBeforeDecode) '1.2.840.113549.1.9.16.2.14': arrayBufferToString (_exts.values ​​[0] .valueBlock.value [1] .valueBeforeDecode) At the moment I'm trying to get data from the extension '1.2.840.113549.1.9.16.2.14' and every time I get an unreadable string ‚&j0‚&f10 *… in response.

Please tell me what encoding are the data in the buffer and how you can get the readable data?

Perhaps many have encountered this and I think it will be useful to get an answer from you.

I am attaching an example data of extension buffer '1.2.840.113549.1.9.16.2.14' in base64.

For reference, BER I get after signing documents using КриптоАРМ 5

rmhrisk commented 3 years ago

This extension seems to provide metadata about the software that created a signature and associated key (https://roskazna.gov.ru/upload/iblock/28a/poryadok_versiya_5_2018.pdf)

Do you have a have a reference for the ASN.1 definition for this extension?

ghost commented 3 years ago

Yes, OID '1.2.643.100.112' contains information about the software that produced the certificate, it is defined in draft-deremin-rfc4491-bis-01. But OID '1.2.840.113549.1.9.16.2.14' is defined in rfc3161 and he it is also unreadable. And most of all I want to first get data from him.

rmhrisk commented 3 years ago

It’s not readable because a decoder for it has not been added to the library. You can manually parse the ASN.1 with ASN1js but for it to be as easy as the other extensions support must be added. I’ve added Stepan and Dima who can point you in the right direction.

microshine commented 3 years ago

ASN.1 modules

OID 1.2.643.100.112

IssuerSignTool ::= SEQUENCE {
  signTool     UTF8String SIZE(1..200),
  cATool       UTF8String SIZE(1..200),
  signToolCert UTF8String SIZE(1..100),
  cAToolCert   UTF8String SIZE(1..100) },

You can manually parse the ASN.1 with ASN1js

const asnIssuerSignTool = asn1js.fromBER(berIssuerSignTool).result;

And use that ASN.1 parsed object to get the required information.

If you are using TypeScript I'd like to suggest you @peculiar/asn1-schema module. It allows creating ASN.1 schemas.

@AsnType({type: AsnTypeTypes.Sequence})
class IssuerSignTool {
  @AsnProp({type: AsnPropTypes.Utf8String})
  signTool: string = "";

  @AsnProp({type: AsnPropTypes.Utf8String})
  cATool: string = "";

  @AsnProp({type: AsnPropTypes.Utf8String})
  signToolCert: string = "";

  @AsnProp({type: AsnPropTypes.Utf8String})
  cAToolCert: string = "";
}

const issuerSignTool = AsnConvert.parse(berIssuerSignTool, IssuerSignTool);
console.log(issuerSignTool.signTool);

OID 1.2.840.113549.1.9.16.2.14

SignatureTimeStampToken ::= TimeStampToken
TimeStampToken ::= ContentInfo

Use

const asnSignatureTimeStampToken = asn1js.fromBER(berSignatureTimeStampToken);
const signatureTimeStampToken = new pkijs.ContentInfo({schema: asnSignatureTimeStampToken.result});
microshine commented 3 years ago

@alex-jss Did you solve your problem?

ghost commented 3 years ago

I did as you wrote for oid 1.2.840.113549.1.9.16.2.14, but I get the error: Object's schema was not verified against input data for ContentInfo.

import {arrayBufferToString, stringToArrayBuffer, toBase64, fromBase64, bufferToHexCodes, utilEncodeTC} from 'pvutils';
import * as asn1js from 'asn1js';
import ContentInfo from 'pkijs/src/ContentInfo';

let buf = stringToArrayBuffer(fromBase64(b64)); // b64 - this is my example i have attached

let resContent: any;
let objContent = asn1js.fromBER(buf);
if (objContent.offset === (-1)) {
    console.log('Can not parse binary data');
} else {
    resContent = new ContentInfo({schema: objContent.result});
}
console.log('resContent', resContent);
microshine commented 3 years ago

@alex-jss Could you share your certificate? You could send it to my email microshine@mail.ru

ghost commented 3 years ago

Thanks for the help. Using @peculiar/asn1-schema, @peculiar/asn1-x509 and @peculiar/asn1-cms solves my question.