Search code examples
angulartypescriptsslx509

How to decode x509 certficate to get expiry date?


I am working on a project to get and display certficate information from an azure integration account with angular/typescript. Part of the requirements is to display the decoded public certificate to a user to find useful information, i.e. expiry date. I have been trying to decode the certificate with the atob() function but it does not decode the certificate properly. Is there a simple way to do this with angular/typscript?

Here is an example of a certifcate:

-----BEGIN CERTIFICATE-----
MIIDqDCCApCgAwIBAgICKg8wDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxJDAiBgNVBAoT
G2dldGFDZXJ0IC0gd3d3LmdldGFjZXJ0LmNvbTAeFw0xOTExMDYwNjMwNDNaFw0y
MDAxMDUwNjMwNDNaMIGJMQswCQYDVQQGEwJBVTELMAkGA1UECBMCU0ExGjAYBgNV
BAcTEVJvc3RyZXZvciBTQSA1MDAwMRAwDgYDVQQKEwdDb3JzdGV4MRcwFQYDVQQD
Ew5BbGJlcnQgTWFyYXNoaTEmMCQGCSqGSIb3DQEJARYXYWxiZXJ0bWFzaHlAb3V0
bG9vay5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdPRTB3j6k
XeylM4Tf7+s7YtjnGgc8Zseh4nX22xpo+sE+pYvOLu4NexprToJ64Yi/SMmBk9u2
0EkrvhWVkA1n8VyU6Oh57Oeg7cDMkqoabJ2CJBn/Z5AF3xrE9GYoymGsfHThd6nQ
JD/HRcErWGyAEwbnNG5CpwySVrMHo2A5va4pDwiDqQAf5rNLP0swtV7Q6UC6eJXs
I5Gbv3bhD8i44DLkj6rbY8uWClhns5XSG5R+rTwoYHkLolLPLj6Em7QtJKPyDsp1
6lzsjLsgzmRixFDhqI3HUlGUnAu6gwwxvP53qhSUi88sKe4M37med5HSAxv+U7A9
rr1js4ey84/9AgMBAAGjSDBGMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgTw
MAsGA1UdDwQEAwIFIDAZBgNVHREEEjAQgg5BbGJlcnQgTWFyYXNoaTANBgkqhkiG
9w0BAQsFAAOCAQEAnXQAvyYE10bc5V9AsjT4x8xyI5AZ6su9OXEDuBFQi2UGvwtb
hhrBZ79Y3KfomXmwtHNVzo6V7dG+9yoDykaKb/Ub72VqF9ZKZArgglMFlGhAk90c
msxWGm7sHLBlt2yjkvnAtt1EtnbOtmuPNGOA7yALTN9/uzBPoTgkjuI1Fkb1uHc1
gynJpqrT0r/qJp0aDxO2SokWYzv/SRCfQTeLMZ5dctHWb8UnsEzt578zYmlDwVof
tOniZVO5TwnXCaWOPjG9XKbW6wHUyMWbulxM9SJUeIjFI2ipQuW8O7Vd94aEyH8o
lc8zFSWoNxamcoX+4ajrs9VbNXythJ91UAtvtA==
-----END CERTIFICATE-----

For reference here is some of the code:

Service

@Injectable()
export class integrationAccountService
{
  constructor(private httpclient: HttpClient, private api: ApiService) { }

  getcertificates(): Observable<Certificate> {
    const httpOptions : Object = {
      headers: new HttpHeaders({
        'Authorization': 'Bearer Token'
      }),
      responseType: 'json'
    };
    return this.httpclient.get<Certificate>(URL, httpOptions);
  }
}

Table Component

export class CertificateTableComponent {

  dataSource: MatTableDataSource<any>;
  //certificates: ValueEntity[] = [];
  data: CertificateRow[] = [];
  columns: string[] = ['name', 'id', 'type', 'publicCertificate'];

  @ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild(MatPaginator, { static:true }) paginator: MatPaginator;

  constructor(private _integrationAccountService: integrationAccountService, public dialog: MatDialog) {
  }

  ngOnInit() {

    this._integrationAccountService.getcertificates().subscribe(response => {
      //this.certificates = response.data;
      this.data = [];
      if (response.value) {
          for (let entity of response.value) {
              let row: CertificateRow = {
                  name: entity.name,
                  id: entity.id,
                  type: entity.type,
                  publicCertificate: entity.properties?.publicCertificate
              };
              this.data.push(row);
              console.log(atob(row.publicCertificate));
          }
      }

      this.dataSource = new MatTableDataSource(this.data);
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;

    })

  }
  applyFilter(event) {
    const filterValue = (event.target as HTMLInputElement).value;

    this.dataSource.filter = filterValue.trim().toLowerCase()
  }

  openDialog(publicCertificate) {
    let dialogRef = this.dialog.open(CertificateViewComponent, {
      data: {
        dialogCert: publicCertificate
      }

    });
  }
}

With this console.log(atob(row.certificate)); does not produce a decoded certifcate, it only displays the certificate as is returned from the api. Is there something I am missing here or another way to go about decoding the certificate?

Thanks in advance!


Solution

  • I've found a solution using the node-forge package. Here is the code I implemented in the table component:

    import * as forge from 'node-forge';
    
    declare var require: any
    const pki = require('node-forge').pki;
    
    const certPem = atob(entity.properties?.publicCertificate)
    const cert = pki.certificateFromPem(certPem)
    
    console.log(cert);