Skip to content

Instantly share code, notes, and snippets.

@rjvdw
Last active June 10, 2019 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjvdw/d1e8be80afe3ac6371a963cbcd724bc1 to your computer and use it in GitHub Desktop.
Save rjvdw/d1e8be80afe3ac6371a963cbcd724bc1 to your computer and use it in GitHub Desktop.
Script to fetch all non-expired certificates with crt.sh (requires Node 12+)
'use strict'
const https = require('https')
const IDENTITIES = [
'rdcl.dev',
'%.rdcl.dev',
'rdcl.nl',
'%.rdcl.nl',
'ruud.online',
'%.ruud.online',
'rudiculous.net',
'%.rudiculous.net',
]
async function main() {
const entries = (await Promise.all(IDENTITIES
.map(encodeURIComponent)
.map(id => `https://crt.sh/atom?identity=${ id }&exclude=expired`)
.map(fetch)
))
.flatMap(parse)
.map(entry => [entry.id, entry])
const results = Object.fromEntries(entries)
console.log(JSON.stringify(results))
}
main().catch(err => console.error(err))
// HELPER METHODS
function fetch(url) {
return new Promise((resolve, reject) => {
https.get(url, res => {
if (res.statusCode !== 200) {
reject(`Request to '${ url }' failed with status code ${ res.statusCode }`)
return
}
res.setEncoding('utf8')
let data = ''
res.on('error', reject)
res.on('data', chunk => data += chunk)
res.on('end', () => resolve(data))
}).on('error', reject)
})
}
function parse(data) {
const matches = data.matchAll(/<entry>[\s\S]*?<\/entry>/g)
return Array.from(matches)
.map(match => match[0])
.map(parseEntry)
}
function parseEntry(entry) {
const entries = ['id', 'summary', 'title', 'published', 'updated']
.map(getTagRegExp)
.map(([key, rx]) => [key, entry.match(rx)])
.map(([key, match]) => [key, match[1]])
.flatMap(([key, value]) => key === 'title'
? parseTitle(value)
: [[key, value]])
return Object.fromEntries(entries)
}
function parseTitle(title) {
const match = title.match(/^\[(.*?)\] Issued by (.*?); Valid from (\S*) to (\S*); Serial number (.*)$/)
if (!match) throw new Error('Failed to parse title: ' + title)
const [, type, issuedBy, validFrom, validTo, serial] = match
return Object.entries({ type, issuedBy, validFrom, validTo, serial })
}
function getTagRegExp(tag) {
return [tag, new RegExp(`<${ tag }[\\s\\S]*?>([\\s\\S]*?)</${ tag }>`)]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment