-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch from node-forge to PKI.js #13894
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:improvement | ||
ui: Add support for ECDSA and Ed25519 certificate views | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,53 @@ | ||
import { helper } from '@ember/component/helper'; | ||
import { pki } from 'node-forge'; | ||
import * as asn1js from 'asn1js'; | ||
import { fromBase64, stringToArrayBuffer } from 'pvutils'; | ||
import { Certificate } from 'pkijs'; | ||
|
||
export function parsePkiCert([model]) { | ||
// model has to be the responseJSON from PKI serializer | ||
if (!model.certificate) { | ||
return; | ||
} | ||
let cert; | ||
// node-forge cannot parse EC (elliptical curve) certs | ||
// set canParse to false if unable to convert a Forge cert from PEM | ||
try { | ||
cert = pki.certificateFromPem(model.certificate); | ||
let cert_base64 = model.certificate.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''); | ||
let cert_der = fromBase64(cert_base64); | ||
let cert_asn1 = asn1js.fromBER(stringToArrayBuffer(cert_der)); | ||
cert = new Certificate({ schema: cert_asn1.result }); | ||
} catch (error) { | ||
console.log('Error parsing certificate:', error, model.certificate); | ||
return { | ||
can_parse: false, | ||
}; | ||
} | ||
const commonName = cert?.subject.getField('CN') ? cert.subject.getField('CN').value : null; | ||
const expiryDate = cert?.validity.notAfter; | ||
const issueDate = cert?.validity.notBefore; | ||
|
||
// We wish to get the CN element out of this certificate's subject. A | ||
// subject is a list of RDNs, where each RDN is a (type, value) tuple | ||
// and where a type is an OID. The OID for CN can be found here: | ||
// | ||
// http://oid-info.com/get/2.5.4.3 | ||
// https://datatracker.ietf.org/doc/html/rfc5280#page-112 | ||
// | ||
// Each value is then encoded as another ASN.1 object; in the case of a | ||
// CommonName field, this is usually a PrintableString, BMPString, or a | ||
// UTF8String. Regardless of encoding, it should be present in the | ||
// valueBlock's value field if it is renderable. | ||
const commonNameOID = '2.5.4.3'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linting hadn't run the first time, but it did now :-D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you for breaking this down and making is so clear to follow. 😍 |
||
const commonNames = cert?.subject?.typesAndValues | ||
.filter((rdn) => rdn?.type === commonNameOID) | ||
.map((rdn) => rdn?.value?.valueBlock?.value); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case anyone was wondering, this does appear to be the correct way to parse the RDN's value: https://github.com/PeculiarVentures/PKI.js/blob/master/src/AttributeTypeAndValue.js#L213-L214 |
||
|
||
// Theoretically, there might be multiple (or no) CommonNames -- but Vault | ||
// presently refuses to issue certificates without CommonNames in most | ||
// cases. For now, return the first CommonName we find. Alternatively, we | ||
// might update our callers to handle multiple, or join them using some | ||
// separator like ','. | ||
const commonName = commonNames ? (commonNames.length ? commonNames[0] : null) : null; | ||
|
||
// Date instances are stored in the value field as the notAfter/notBefore | ||
// field themselves are Time values. | ||
const expiryDate = cert?.notAfter?.value; | ||
const issueDate = cert?.notBefore?.value; | ||
return { | ||
can_parse: true, | ||
common_name: commonName, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5087,6 +5087,13 @@ asn1@~0.2.3: | |
dependencies: | ||
safer-buffer "~2.1.0" | ||
|
||
asn1js@^2.1.1, asn1js@^2.2.0: | ||
version "2.2.0" | ||
resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-2.2.0.tgz#d890fcdda86b8a005693df14a986bfb2c2069c57" | ||
integrity sha512-oagLNqpfNv7CvmyMoexMDNyVDSiq1rya0AEUgcLlNHdHgNl6U/hi8xY370n5y+ZIFEXOx0J4B1qF2NDjMRxklA== | ||
dependencies: | ||
pvutils latest | ||
|
||
assert-never@^1.1.0, assert-never@^1.2.1: | ||
version "1.2.1" | ||
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" | ||
|
@@ -7353,6 +7360,11 @@ [email protected]: | |
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" | ||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== | ||
|
||
bytestreamjs@^1.0.29: | ||
version "1.0.29" | ||
resolved "https://registry.yarnpkg.com/bytestreamjs/-/bytestreamjs-1.0.29.tgz#691f8ee8e5a150c61b925993a3eec0911ed17f1d" | ||
integrity sha512-Mri3yqoo9YvdaSvD5OYl4Rdu9zCBJInW/Ez31sdlNY4ikMy//EvTTmidfLcs0e+NBvKVEpPzYvJAesjgMdjnZg== | ||
|
||
cacache@^12.0.2: | ||
version "12.0.4" | ||
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" | ||
|
@@ -16125,11 +16137,6 @@ node-fetch@^2.6.1: | |
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" | ||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== | ||
|
||
node-forge@^0.10.0: | ||
version "0.10.0" | ||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" | ||
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== | ||
|
||
node-gyp@^3.8.0: | ||
version "3.8.0" | ||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" | ||
|
@@ -17142,6 +17149,15 @@ pkg-up@^2.0.0: | |
dependencies: | ||
find-up "^2.1.0" | ||
|
||
pkijs@^2.2.2: | ||
version "2.2.2" | ||
resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-2.2.2.tgz#d0780379a2fb80c892c3ead4bcfb42675b67a982" | ||
integrity sha512-xRTEW9LgUeHBe5hRCC4EHvLbO6o3L/t8uEk8cTaSMVEjEcy2G5qJ/bY2ndvrGgZlKDThnTrM4Xlwu8Qpyr6mOg== | ||
dependencies: | ||
asn1js "^2.1.1" | ||
bytestreamjs "^1.0.29" | ||
pvutils "^1.0.17" | ||
|
||
please-upgrade-node@^3.2.0: | ||
version "3.2.0" | ||
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" | ||
|
@@ -17615,6 +17631,11 @@ puppeteer-core@^2.1.1: | |
rimraf "^2.6.1" | ||
ws "^6.1.0" | ||
|
||
pvutils@^1.0.17, pvutils@latest: | ||
version "1.0.17" | ||
resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.0.17.tgz#ade3c74dfe7178944fe44806626bd2e249d996bf" | ||
integrity sha512-wLHYUQxWaXVQvKnwIDWFVKDJku9XDCvyhhxoq8dc5MFdIlRenyPI9eSfEtcvgHgD7FlvCyGAlWgOzRnZD99GZQ== | ||
|
||
q@^1.1.2: | ||
version "1.5.1" | ||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉