2020-01-02 14:39:00 +01:00
/ * *
* @ author nehagopinath [ nehagowri94 @ gmail . com ]
* @ copyright Crown Copyright 2020
* @ license Apache - 2.0
* /
import Operation from "../Operation.mjs" ;
import r from "jsrsasign" ;
import { formatDnStr } from "../lib/PublicKey" ;
/ * *
* ParseX509CertificateBundles operation
* /
class ParseX509CertificateBundles extends Operation {
/ * *
* ParseX509CertificateBundles constructor
* /
constructor ( ) {
super ( ) ;
this . name = "ParseX509CertificateBundles" ;
this . module = "PublicKey" ;
this . description = "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.<br><br>This operation displays the required contents of different certificates bundled in the input file in a human readable format, similar to the openssl command line tool.<br><br>Tags: X509, server hello, handshake" ;
this . infoURL = "https://wikipedia.org/wiki/X.509" ;
this . inputType = "string" ;
this . outputType = "string" ;
this . args = [
{
"name" : "Input format" ,
"type" : "option" ,
2020-01-21 16:53:35 +01:00
"value" : [ "PEM" ]
2020-01-02 14:39:00 +01:00
}
] ;
this . patterns = [
{
"match" : "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$" ,
"flags" : "i" ,
"args" : [
"PEM"
]
}
] ;
}
/ * *
* @ param { string } input
* @ param { Object [ ] } args
* @ returns { string }
* /
2020-01-21 16:53:35 +01:00
2020-01-02 14:39:00 +01:00
run ( input , args ) {
2020-01-21 16:53:35 +01:00
2020-01-02 14:39:00 +01:00
if ( ! input . length ) {
return "No input" ;
}
2020-01-21 16:53:35 +01:00
const regex = /^-----BEGIN CERTIFICATE-----\r?\n((?:(?!-----).*\r?\n)*)-----END CERTIFICATE-----/gm ;
let m ;
let res = "" ;
while ( ( m = regex . exec ( input ) ) !== null ) {
// This is necessary to avoid infinite loops with zero-width matches
if ( m . index === regex . lastIndex ) {
regex . lastIndex ++ ;
}
//console.log(m[1]);
res += "\nCertificate:\n" + parseCert ( "-----BEGIN CERTIFICATE-----" + "\n" + m [ 1 ] + "\n" + "-----END CERTIFICATE-----" ) ;
2020-01-02 14:39:00 +01:00
}
2020-01-21 16:53:35 +01:00
return "Parsed Certificates:\n" + res ;
}
}
function parseCert ( input ) {
const cert = new r . X509 ( ) ;
cert . readCertPEM ( input ) ;
2020-01-02 14:39:00 +01:00
const issuer = cert . getIssuerString ( ) ,
subject = cert . getSubjectString ( ) ;
let extensions = "" ;
// Extensions
try {
// extensions =cert.getInfo();
2020-01-21 16:53:35 +01:00
extensions = cert . getInfo ( ) . split ( "X509v3 Extensions:\n" ) [ 1 ] . split ( "signature" ) [ 0 ] ;
} catch ( err ) {
}
2020-01-02 14:39:00 +01:00
const issuerStr = formatDnStr ( issuer , 2 ) ,
nbDate = formatDate ( cert . getNotBefore ( ) ) ,
naDate = formatDate ( cert . getNotAfter ( ) ) ,
subjectStr = formatDnStr ( subject , 2 ) ;
return ` Validity
Not Before : $ { nbDate } ( dd - mm - yyyy hh : mm : ss ) ( $ { cert . getNotBefore ( ) } )
Not After : $ { naDate } ( dd - mm - yyyy hh : mm : ss ) ( $ { cert . getNotAfter ( ) } )
Issuer
$ { issuerStr }
Subject
$ { subjectStr }
2020-01-21 16:53:35 +01:00
Extensions / basicConstraints
2020-01-02 14:39:00 +01:00
$ { extensions } ` ;
}
/ * *
* Formats dates .
*
* @ param { string } dateStr
* @ returns { string }
* /
2020-01-21 16:53:35 +01:00
function formatDate ( dateStr ) {
2020-01-02 14:39:00 +01:00
if ( dateStr . length === 13 ) { // UTC Time
dateStr = ( dateStr [ 0 ] < "5" ? "20" : "19" ) + dateStr ;
}
return dateStr [ 6 ] + dateStr [ 7 ] + "/" +
dateStr [ 4 ] + dateStr [ 5 ] + "/" +
dateStr [ 0 ] + dateStr [ 1 ] + dateStr [ 2 ] + dateStr [ 3 ] + " " +
dateStr [ 8 ] + dateStr [ 9 ] + ":" +
dateStr [ 10 ] + dateStr [ 11 ] + ":" +
dateStr [ 12 ] + dateStr [ 13 ] ;
}
export default ParseX509CertificateBundles ;