check-idp-metadata.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*
  2. Checks the SAML metadata provided by the IdP.
  3. Currently, only checking the valid from and to dates for the certificate
  4. Run with: node check-idp-metadata /path/idp-metadata.xml
  5. */
  6. import { Certificate } from '@fidm/x509'
  7. import _ from 'lodash'
  8. import moment from 'moment'
  9. import fs from 'fs'
  10. import xml2js from 'xml2js'
  11. function checkCertDates(signingKey) {
  12. let cert = _.get(signingKey, [
  13. 'ds:KeyInfo',
  14. 0,
  15. 'ds:X509Data',
  16. 0,
  17. 'ds:X509Certificate',
  18. 0,
  19. ])
  20. if (!cert) {
  21. throw new Error('no cert')
  22. }
  23. cert = cert.replace(/\s/g, '')
  24. const certificate = Certificate.fromPEM(
  25. Buffer.from(
  26. `-----BEGIN CERTIFICATE-----\n${cert}\n-----END CERTIFICATE-----`,
  27. 'utf8'
  28. )
  29. )
  30. const validFrom = moment(certificate.validFrom)
  31. const validTo = moment(certificate.validTo)
  32. return {
  33. validFrom,
  34. validTo,
  35. }
  36. }
  37. async function main() {
  38. const [, , file] = process.argv
  39. console.log('Checking SAML metadata')
  40. const data = await fs.promises.readFile(file, 'utf8')
  41. const parser = new xml2js.Parser()
  42. const xml = await parser.parseStringPromise(data)
  43. const idp = xml.EntityDescriptor.IDPSSODescriptor
  44. const keys = idp[0].KeyDescriptor
  45. const signingKey =
  46. keys.length === 1
  47. ? keys[0]
  48. : keys.find(key => _.get(key, ['$', 'use']) === 'signing')
  49. const certDates = checkCertDates(signingKey)
  50. console.log(
  51. `SSO certificate is valid from ${certDates.validFrom} to ${certDates.validTo}`
  52. )
  53. }
  54. main()