Last active
June 10, 2019 08:25
-
-
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+)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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