From b17c2f0b2daf712e65393fa6efaae21020e2c610 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Tue, 20 Jun 2023 23:02:31 +0100 Subject: [PATCH] Adds SSL cert checking results --- src/components/Results/SslCert.tsx | 104 +++++++++++++++++++++++++++++ src/pages/Results.tsx | 23 ++++++- src/utils/result-processor.ts | 5 +- 3 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/components/Results/SslCert.tsx diff --git a/src/components/Results/SslCert.tsx b/src/components/Results/SslCert.tsx new file mode 100644 index 0000000..79579d1 --- /dev/null +++ b/src/components/Results/SslCert.tsx @@ -0,0 +1,104 @@ + +import styled from 'styled-components'; +import { Whois } from 'utils/result-processor'; +import colors from 'styles/colors'; +import Card from 'components/Form/Card'; +import Heading from 'components/Form/Heading'; + +const Outer = styled(Card)``; + +const Row = styled.div` + display: flex; + justify-content: space-between; + padding: 0.25rem; + &:not(:last-child) { border-bottom: 1px solid ${colors.primary}; } + span.lbl { font-weight: bold; } + span.val { + max-width: 200px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +`; + +const formatDate = (dateString: string): string => { + const date = new Date(dateString); + const formatter = new Intl.DateTimeFormat('en-GB', { + day: 'numeric', + month: 'long', + year: 'numeric' + }); + return formatter.format(date); +} + +const DataRow = (props: { lbl: string, val: string }) => { + const { lbl, val } = props; + return ( + + {lbl} + {val} + + ); +}; + + +function getExtendedKeyUsage(oids: string[]) { + const oidMap: { [key: string]: string } = { + "1.3.6.1.5.5.7.3.1": "TLS Web Server Authentication", + "1.3.6.1.5.5.7.3.2": "TLS Web Client Authentication", + "1.3.6.1.5.5.7.3.3": "Code Signing", + "1.3.6.1.5.5.7.3.4": "Email Protection (SMIME)", + "1.3.6.1.5.5.7.3.8": "Time Stamping", + "1.3.6.1.5.5.7.3.9": "OCSP Signing", + "1.3.6.1.5.5.7.3.5": "IPSec End System", + "1.3.6.1.5.5.7.3.6": "IPSec Tunnel", + "1.3.6.1.5.5.7.3.7": "IPSec User", + "1.3.6.1.5.5.8.2.2": "IKE Intermediate", + "2.16.840.1.113730.4.1": "Netscape Server Gated Crypto", + "1.3.6.1.4.1.311.10.3.3": "Microsoft Server Gated Crypto", + "1.3.6.1.4.1.311.10.3.4": "Microsoft Encrypted File System", + "1.3.6.1.4.1.311.20.2.2": "Microsoft Smartcard Logon", + "1.3.6.1.4.1.311.10.3.12": "Microsoft Document Signing", + "0.9.2342.19200300.100.1.3": "Email Address (in Subject Alternative Name)", + }; + const results = oids.map(oid => oidMap[oid] || oid); + return results.filter((item, index) => results.indexOf(item) === index); +} + + +const ListRow = (props: { list: string[], title: string }) => { + const { list, title } = props; + return ( + <> + {title} + { list.map((entry: string, index: number) => { + return ( + { entry } + )} + )} + +); +} + +const SslCertCard = (props: { sslCert: any }): JSX.Element => { + const { subject, issuer, fingerprint, serialNumber, asn1Curve, nistCurve, valid_to, valid_from, ext_key_usage } = props.sslCert; + return ( + + SSL Info + { subject && } + { issuer?.O && } + + { asn1Curve && } + { nistCurve && } + { valid_to && } + { valid_from && } + { serialNumber && } + { fingerprint && } + { fingerprint && } + { ext_key_usage && } + + + ); +} + +export default SslCertCard; diff --git a/src/pages/Results.tsx b/src/pages/Results.tsx index 0349fd1..ee35ccf 100644 --- a/src/pages/Results.tsx +++ b/src/pages/Results.tsx @@ -12,6 +12,7 @@ import WhoIsCard from 'components/Results/WhoIs'; import BuiltWithCard from 'components/Results/BuiltWith'; import LighthouseCard from 'components/Results/Lighthouse'; import ScreenshotCard from 'components/Results/Screenshot'; +import SslCertCard from 'components/Results/SslCert'; import keys from 'utils/get-keys'; import { determineAddressType, AddressType } from 'utils/address-type-checker'; @@ -51,7 +52,7 @@ const Header = styled(Card)` interface ResultsType { serverLocation?: ServerLocation, serverInfo?: ServerInfo, - hostNames?: HostNames, + hostNames?: HostNames | null, }; const Results = (): JSX.Element => { @@ -60,6 +61,7 @@ const Results = (): JSX.Element => { const [ whoIsResults, setWhoIsResults ] = useState(); const [ technologyResults, setTechnologyResults ] = useState(); const [ lighthouseResults, setLighthouseResults ] = useState(); + const [ sslResults, setSslResults ] = useState(); const [ screenshotResult, setScreenshotResult ] = useState(); const [ ipAddress, setIpAddress ] = useState(undefined); const [ addressType, setAddressType ] = useState('empt'); @@ -91,6 +93,17 @@ const Results = (): JSX.Element => { } }, [address]); + /* Get SSL info */ + useEffect(() => { + fetch(`/ssl-check?url=${address}`) + .then(response => response.json()) + .then(response => { + console.log(response); + setSslResults(response); + }) + .catch(err => console.error(err)); + }, [address]) + /* Get Lighthouse report */ useEffect(() => { fetch(`/lighthouse-report?url=${address}`) @@ -184,16 +197,20 @@ const Results = (): JSX.Element => {
Results - {address} + + { address && } + {address} +
{ locationResults && } { results.serverInfo && } - { results.hostNames && } + { results?.hostNames && } { whoIsResults && } { lighthouseResults && } { screenshotResult && } { technologyResults && } + { sslResults && }
); diff --git a/src/utils/result-processor.ts b/src/utils/result-processor.ts index f5b84ce..e50309d 100644 --- a/src/utils/result-processor.ts +++ b/src/utils/result-processor.ts @@ -75,8 +75,11 @@ export interface HostNames { hostnames: string[], }; -export const getHostNames = (response: any): HostNames => { +export const getHostNames = (response: any): HostNames | null => { const { hostnames, domains } = response; + if ((!domains || domains.length < 1) && (!hostnames || hostnames.length < 1)) { + return null; + } const results: HostNames = { domains: domains || [], hostnames: hostnames || [],