@peculiar/fortify-client-core
Version:
Fortify client core API for quickly connect to Fortify App
143 lines (142 loc) • 5.21 kB
JavaScript
/**
* @license
* Copyright (c) Peculiar Ventures, LLC.
*
* This source code is licensed under the BSD 3-Clause license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Certificate, id_ce_keyUsage, id_ce_certificatePolicies, id_ce_basicConstraints, } from '@peculiar/asn1-x509';
import { id_pe_qcStatements, } from '@peculiar/asn1-x509-qualified';
import { AsnConvert } from '@peculiar/asn1-schema';
import { AsnData } from './asn_data';
import { Extension } from './extension';
/**
* https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcCompliance
*/
const QC_COMPLIANT = '0.4.0.1862.1.1';
/**
* https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcSSCD
*/
const QC_SSCD = '0.4.0.1862.1.4';
/**
* http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.01.01_60/en_31941205v020101p.pdf - id-etsi-qct-eseal
*/
const QCT_ESEAL = '0.4.0.1862.1.6.2';
/**
* http://www.etsi.org/deliver/etsi_ts/101400_101499/101456/01.04.03_60/ts_101456v010403p.pdf
*/
const QCP_PUBLIC_WITH_SSCD = '0.4.0.1456.1.1';
/**
* http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf
*/
const QCP_LEGAL = '0.4.0.194112.1.1';
/**
* http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf
*/
const QCP_NATURAL_QSCD = '0.4.0.194112.1.2';
/**
* http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf
*/
const QCP_LEGAL_QSCD = '0.4.0.194112.1.3';
export class X509Schema extends AsnData {
constructor(raw) {
super(raw, Certificate);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.extensions = [];
this.parseExtensions();
}
parseExtensions() {
const { tbsCertificate } = this.asn;
if (tbsCertificate.extensions) {
this.extensions = tbsCertificate.extensions
.map((e) => new Extension(AsnConvert.serialize(e)));
}
}
getExtensionByOid(oid) {
if (!this.extensions.length) {
return undefined;
}
for (let i = 0; i < this.extensions.length; i += 1) {
const extension = this.extensions[i];
if (extension && extension.asn.extnID === oid) {
return extension;
}
}
return undefined;
}
hasKeyUsage(keyUsageTypes) {
/**
* Return `false` if `keyUsageTypes` argument is empty or has 0 length.
*/
if (!keyUsageTypes || !keyUsageTypes.length) {
return false;
}
const keyUsageExtension = this.getExtensionByOid(id_ce_keyUsage);
/**
* Return `false` if `keyUsage` extension doesn't exist.
*/
if (!keyUsageExtension) {
return false;
}
const keyUsageExtensionTypes = keyUsageExtension.value.toJSON();
/**
* Return `false` if `keyUsageExtensionTypes` extension has 0 length.
*/
if (!keyUsageExtensionTypes.length) {
return false;
}
for (let i = 0; i < keyUsageTypes.length; i += 1) {
const type = keyUsageTypes[i];
if (typeof type === 'string' && keyUsageExtensionTypes.includes(type)) {
return true;
}
if (Array.isArray(type) && type.every((t) => keyUsageExtensionTypes.includes(t))) {
return true;
}
}
return false;
}
/**
* https://github.com/open-eid/libdigidocpp/blob/00ea32a0f94f4889b790ed45a100aae521f07392/src/crypto/X509CertStore.cpp#L258
*/
isQualified(qualifiedCertificateStatements = []) {
const policies = this.getExtensionByOid(id_ce_certificatePolicies);
if (!policies) {
return false;
}
const qcStatements = this.getExtensionByOid(id_pe_qcStatements);
if (!qcStatements) {
return false;
}
const policiesValues = policies.value.map((info) => info.policyIdentifier);
const qcStatementsValues = qcStatements.value.map((statement) => statement.statementId);
const isQCCompliant = qcStatementsValues.includes(QC_COMPLIANT);
let isQSCD = policiesValues.includes(QCP_PUBLIC_WITH_SSCD)
|| policiesValues.includes(QCP_LEGAL_QSCD)
|| policiesValues.includes(QCP_NATURAL_QSCD)
|| qcStatementsValues.includes(QC_SSCD);
const isESeal = policiesValues.includes(QCP_LEGAL)
|| qcStatementsValues.includes(QCT_ESEAL);
if (qualifiedCertificateStatements.length) {
qualifiedCertificateStatements.forEach((statement) => {
if (qcStatementsValues.includes(statement)) {
isQSCD = true;
}
});
}
if (!((isQCCompliant && isQSCD) || isESeal)) {
return false;
}
return true;
}
/**
* Return value based on `BasicConstraints` extension `cA` value.
*/
isCA() {
const extension = this.getExtensionByOid(id_ce_basicConstraints);
if (!extension) {
return false;
}
return extension.value.cA;
}
}