Skip to content

Commit

Permalink
table query done
Browse files Browse the repository at this point in the history
  • Loading branch information
kayra1 committed Jun 13, 2024
1 parent 875a6d0 commit fc08581
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 10 deletions.
53 changes: 53 additions & 0 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"dependencies": {
"next": "14.2.3",
"pkijs": "^3.1.0",
"react": "^18",
"react-dom": "^18",
"react-query": "^3.39.3",
Expand Down
17 changes: 7 additions & 10 deletions ui/src/app/certificate_requests/row.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { useState, Dispatch, SetStateAction } from "react"
const extractCSR = (csrPemString: string) => {
//TODO
}
import { extractCSR, extractCert } from "../utils"

const extractCert = (certPemString: string) => {
//TODO
}

type rowProps = {
id: number,
Expand All @@ -18,6 +13,9 @@ type rowProps = {
export default function Row({ id, csr, certificate, ActionMenuExpanded, setActionMenuExpanded }: rowProps) {
const [detailsMenuOpen, setDetailsMenuOpen] = useState<boolean>(false)

const csrObj = extractCSR(csr)
const certObj = extractCert(certificate)

const toggleActionMenu = () => {
if (ActionMenuExpanded == id) {
setActionMenuExpanded(0)
Expand All @@ -36,10 +34,10 @@ export default function Row({ id, csr, certificate, ActionMenuExpanded, setActio
onClick={() => setDetailsMenuOpen(!detailsMenuOpen)}>
<i className="p-icon--chevron-down p-contextual-menu__indicator"></i>
</button>
<span> example.com</span>
<span>{csrObj.subjects.find((e) => e.type == "Common Name")?.value}</span>
</td>
<td className="" data-test-column="status">{certificate == "" ? "outstanding" : (certificate == "rejected" ? "rejected" : "fulfilled")}</td>
<td className="" data-test-column="status">{certificate == "" ? "" : (certificate == "rejected" ? "" : "date")}</td>
<td className="" data-test-column="status">{certificate == "" ? "" : (certificate == "rejected" ? "" : certObj?.notAfter)}</td>
<td className="has-overflow" data-heading="Actions">
<span className="p-contextual-menu--center u-no-margin--bottom">
<button
Expand Down Expand Up @@ -68,8 +66,7 @@ export default function Row({ id, csr, certificate, ActionMenuExpanded, setActio
<td id="expanded-row" className="p-table__expanding-panel" aria-hidden={detailsMenuOpen? "false": "true"}>
<div className="row">
<div className="col-8">
<p><b>Common Name</b>: example.com</p>
<p><b>Subject Alternative Names</b>: example.com, 127.0.0.1, 1.2.3.4.5.56</p>
<p><b>Common Name</b>: {csrObj.subjects.find((e) => e.type == "Common Name")?.value}</p>
</div>
</div>
</td>
Expand Down
119 changes: 119 additions & 0 deletions ui/src/app/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { CertificationRequest, Certificate } from "pkijs";
import { fromBER } from "asn1js";


export const oidToName =(oid: string) => {
const map :{ [key: string]: string } = {
// Subject OID's
"2.5.4.3": "Common Name",
"2.5.4.6": "Country",
"2.5.4.7": "Locality",
"2.5.4.8": "State or Province",
"2.5.4.9": "Street Address",
"2.5.4.97": "Organization Identifier",
"2.5.4.10": "Organization Name",
"2.5.4.11": "Organizational Unit Name",
"2.5.4.5": "Serial Number",
"2.5.4.4": "Surname",
"2.5.4.42": "Given Name",
"2.5.4.12": "Title",
"2.5.4.43": "Initials",
"2.5.4.44": "Generation Qualifier",
"2.5.4.45": "X500 Unique Identifier",
"2.5.4.46": "Dn Qualifier",
"2.5.4.65": "Pseudonym",
"0.9.2342.19200300.100.1.1": "User Id",
"0.9.2342.19200300.100.1.25": "Domain Component",
"1.2.840.113549.1.9.1": "Email Address",
"1.3.6.1.4.1.311.60.2.1.3": "Jurisdiction Country-Name",
"1.3.6.1.4.1.311.60.2.1.1": "Jurisdiction Locality-Name",
"1.3.6.1.4.1.311.60.2.1.2": "Jurisdiction State Or Province Name",
"2.5.4.15": "Business Category",
"2.5.4.16": "Postal Address",
"2.5.4.17": "Postal Code",
"1.2.643.3.131.1.1": "Inn",
"1.2.643.100.1": "Ogrn",
"1.2.643.100.3": "Snils",
"1.2.840.113549.1.9.2": "Unstructured Name",
// OID for pkcs-9-at-extensionRequest
"1.2.840.113549.1.9.14": "Extension Request",
// OID for basicConstraint
"2.5.29.19": "Basic Constraint"
}
if (!(oid in map)) {
throw new Error("oid not recognized: " + oid)
}
return map[oid]
}

export const extractCSR = (csrPemString: string) => {
// Decode PEM to DER
const pemHeader = "-----BEGIN CERTIFICATE REQUEST-----";
const pemFooter = "-----END CERTIFICATE REQUEST-----";
const pemContents = csrPemString.substring(pemHeader.length, csrPemString.length - pemFooter.length);
const binaryDerString = window.atob(pemContents);
const binaryDer = new Uint8Array(binaryDerString.length);
for (let i = 0; i < binaryDerString.length; i++) {
binaryDer[i] = binaryDerString.charCodeAt(i);
}

// Parse DER encoded CSR
const asn1 = fromBER(binaryDer.buffer);
if (asn1.offset === -1) {
throw new Error("Error parsing certificate request");

Check failure on line 63 in ui/src/app/utils.ts

View workflow job for this annotation

GitHub Actions / unit-test-frontend / nextjs-unit-tests

src/app/certificate_requests/row.test.tsx > Certificate Requests Table Row

Error: Error parsing certificate request ❯ Module.extractCSR src/app/utils.ts:63:15 ❯ Row src/app/certificate_requests/row.tsx:16:20 ❯ renderWithHooks node_modules/react-dom/cjs/react-dom.development.js:15486:18 ❯ mountIndeterminateComponent node_modules/react-dom/cjs/react-dom.development.js:20103:13 ❯ beginWork node_modules/react-dom/cjs/react-dom.development.js:21626:16 ❯ beginWork$1 node_modules/react-dom/cjs/react-dom.development.js:27465:14 ❯ performUnitOfWork node_modules/react-dom/cjs/react-dom.development.js:26599:12 ❯ workLoopSync node_modules/react-dom/cjs/react-dom.development.js:26505:5 ❯ renderRootSync node_modules/react-dom/cjs/react-dom.development.js:26473:7 ❯ recoverFromConcurrentError node_modules/react-dom/cjs/react-dom.development.js:25889:20
}

// Load CSR object
const csr = new CertificationRequest({ schema: asn1.result });

// Extract subject information from CSR
const subjects = csr.subject.typesAndValues.map(typeAndValue => ({
type: oidToName(typeAndValue.type),
value: typeAndValue.value.valueBlock.value
}));

// Look for extensions attribute in CSR
const attributes = csr.attributes?.map(typeAndValue => ({
type: oidToName(typeAndValue.type),
value: typeAndValue.values
}))
return {subjects}
}

export const extractCert = (certPemString: string) => {
if (certPemString == "" || certPemString == "rejected") {return}
// Decode PEM to DER
const pemHeader = "-----BEGIN CERTIFICATE-----";
const pemFooter = "-----END CERTIFICATE-----";
const pemContents = certPemString.substring(pemHeader.length, certPemString.length - pemFooter.length);
const binaryDerString = window.atob(pemContents);
const binaryDer = new Uint8Array(binaryDerString.length);
for (let i = 0; i < binaryDerString.length; i++) {
binaryDer[i] = binaryDerString.charCodeAt(i);
}

// Parse DER encoded certificate
const asn1 = fromBER(binaryDer.buffer);
if (asn1.offset === -1) {
throw new Error("Error parsing certificate");
}

// Load Certificate object
const cert = new Certificate({ schema: asn1.result });

// Extract relevant information from certificate
const subject = cert.subject.typesAndValues.map(typeAndValue => ({
type: typeAndValue.type,
value: typeAndValue.value.valueBlock.value
}));

const issuer = cert.issuer.typesAndValues.map(typeAndValue => ({
type: typeAndValue.type,
value: typeAndValue.value.valueBlock.value
}));

const notBefore = cert.notBefore.value.toString();
const notAfter = cert.notAfter.value.toString();

return {notAfter}
}

0 comments on commit fc08581

Please sign in to comment.