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 || [],