domainlooker
Version:
🕵️ Mission-critical domain intelligence gathering tool with spy-themed interface. Comprehensive WHOIS, DNS, SSL, network analysis, subdomain discovery, and API-ready JSON exports.
66 lines • 2.46 kB
JavaScript
import * as tls from 'tls';
export class SSLService {
async getCertificate(domain, port = 443) {
return new Promise((resolve, reject) => {
const options = {
host: domain,
port: port,
servername: domain,
rejectUnauthorized: false
};
const socket = tls.connect(options, () => {
const cert = socket.getPeerCertificate(true);
if (!cert || Object.keys(cert).length === 0) {
socket.destroy();
reject(new Error('No certificate found'));
return;
}
const result = {
issuer: this.formatCertificateName(cert.issuer),
subject: this.formatCertificateName(cert.subject),
validFrom: cert.valid_from,
validTo: cert.valid_to,
fingerprint: cert.fingerprint,
serialNumber: cert.serialNumber,
signatureAlgorithm: cert.sigalg,
isValid: this.isCertificateValid(cert),
daysUntilExpiry: this.getDaysUntilExpiry(cert.valid_to)
};
socket.destroy();
resolve(result);
});
socket.on('error', (error) => {
reject(error);
});
socket.setTimeout(10000, () => {
socket.destroy();
reject(new Error('SSL connection timeout'));
});
});
}
formatCertificateName(certName) {
if (typeof certName === 'string')
return certName;
const parts = [];
if (certName.CN)
parts.push(`CN=${certName.CN}`);
if (certName.O)
parts.push(`O=${certName.O}`);
if (certName.C)
parts.push(`C=${certName.C}`);
return parts.join(', ');
}
isCertificateValid(cert) {
const now = new Date();
const validFrom = new Date(cert.valid_from);
const validTo = new Date(cert.valid_to);
return now >= validFrom && now <= validTo;
}
getDaysUntilExpiry(validTo) {
const expiryDate = new Date(validTo);
const now = new Date();
const diffTime = expiryDate.getTime() - now.getTime();
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
}
//# sourceMappingURL=ssl.js.map