1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
#
#
# Nim's Runtime Library
# (c) Copyright 2017 Nim contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Scan for SSL/TLS CA certificates on disk
## The default locations can be overridden using the SSL_CERT_FILE and
## SSL_CERT_DIR environment variables.
import std/[os, strutils]
# FWIW look for files before scanning entire dirs.
when defined(macosx):
const certificatePaths = [
"/etc/ssl/cert.pem",
"/System/Library/OpenSSL/certs/cert.pem"
]
elif defined(linux):
const certificatePaths = [
# Debian, Ubuntu, Arch: maintained by update-ca-certificates, SUSE, Gentoo
# NetBSD (security/mozilla-rootcerts)
# SLES10/SLES11, https://golang.org/issue/12139
"/etc/ssl/certs/ca-certificates.crt",
# OpenSUSE
"/etc/ssl/ca-bundle.pem",
# Red Hat 5+, Fedora, Centos
"/etc/pki/tls/certs/ca-bundle.crt",
# Red Hat 4
"/usr/share/ssl/certs/ca-bundle.crt",
# Fedora/RHEL
"/etc/pki/tls/certs",
# Android
"/data/data/com.termux/files/usr/etc/tls/cert.pem",
"/system/etc/security/cacerts",
]
elif defined(bsd):
const certificatePaths = [
# Debian, Ubuntu, Arch: maintained by update-ca-certificates, SUSE, Gentoo
# NetBSD (security/mozilla-rootcerts)
# SLES10/SLES11, https://golang.org/issue/12139
"/etc/ssl/certs/ca-certificates.crt",
# FreeBSD (security/ca-root-nss package)
"/usr/local/share/certs/ca-root-nss.crt",
# OpenBSD, FreeBSD (optional symlink)
"/etc/ssl/cert.pem",
# FreeBSD
"/usr/local/share/certs",
# NetBSD
"/etc/openssl/certs",
]
else:
const certificatePaths = [
# Debian, Ubuntu, Arch: maintained by update-ca-certificates, SUSE, Gentoo
# NetBSD (security/mozilla-rootcerts)
# SLES10/SLES11, https://golang.org/issue/12139
"/etc/ssl/certs/ca-certificates.crt",
# OpenSUSE
"/etc/ssl/ca-bundle.pem",
# Red Hat 5+, Fedora, Centos
"/etc/pki/tls/certs/ca-bundle.crt",
# Red Hat 4
"/usr/share/ssl/certs/ca-bundle.crt",
# FreeBSD (security/ca-root-nss package)
"/usr/local/share/certs/ca-root-nss.crt",
# CentOS/RHEL 7
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
# OpenBSD, FreeBSD (optional symlink)
"/etc/ssl/cert.pem",
# Fedora/RHEL
"/etc/pki/tls/certs",
# Android
"/system/etc/security/cacerts",
# FreeBSD
"/usr/local/share/certs",
# NetBSD
"/etc/openssl/certs",
]
when defined(haiku):
const
B_FIND_PATH_EXISTING_ONLY = 0x4
B_FIND_PATH_DATA_DIRECTORY = 6
proc find_paths_etc(architecture: cstring, baseDirectory: cint,
subPath: cstring, flags: uint32,
paths: var ptr UncheckedArray[cstring],
pathCount: var csize_t): int32
{.importc, header: "<FindDirectory.h>".}
proc free(p: pointer) {.importc, header: "<stdlib.h>".}
iterator scanSSLCertificates*(useEnvVars = false): string =
## Scan for SSL/TLS CA certificates on disk.
##
## if `useEnvVars` is true, the SSL_CERT_FILE and SSL_CERT_DIR
## environment variables can be used to override the certificate
## directories to scan or specify a CA certificate file.
if useEnvVars and existsEnv("SSL_CERT_FILE"):
yield getEnv("SSL_CERT_FILE")
elif useEnvVars and existsEnv("SSL_CERT_DIR"):
let p = getEnv("SSL_CERT_DIR")
for fn in joinPath(p, "*").walkFiles():
yield fn
else:
when defined(windows):
const cacert = "cacert.pem"
let pem = getAppDir() / cacert
if fileExists(pem):
yield pem
else:
let path = getEnv("PATH")
for candidate in split(path, PathSep):
if candidate.len != 0:
let x = (if candidate[0] == '"' and candidate[^1] == '"':
substr(candidate, 1, candidate.len-2) else: candidate) / cacert
if fileExists(x):
yield x
elif not defined(haiku):
for p in certificatePaths:
if p.endsWith(".pem") or p.endsWith(".crt"):
if fileExists(p):
yield p
elif dirExists(p):
# check if it's a dir where each cert is one file
# named by it's hasg
for fn in joinPath(p, "*.0").walkFiles:
yield p.normalizePathEnd(true)
break
for fn in joinPath(p, "*").walkFiles():
yield fn
else:
var
paths: ptr UncheckedArray[cstring]
size: csize_t
let err = find_paths_etc(
nil, B_FIND_PATH_DATA_DIRECTORY, "ssl/CARootCertificates.pem",
B_FIND_PATH_EXISTING_ONLY, paths, size
)
if err == 0:
defer: free(paths)
for i in 0 ..< size:
yield $paths[i]
# Certificates management on windows
# when defined(windows) or defined(nimdoc):
#
# import std/openssl
#
# type
# PCCertContext {.final, pure.} = pointer
# X509 {.final, pure.} = pointer
# CertStore {.final, pure.} = pointer
#
# # OpenSSL cert store
#
# {.push stdcall, dynlib: "kernel32", importc.}
#
# proc CertOpenSystemStore*(hprov: pointer=nil, szSubsystemProtocol: cstring): CertStore
#
# proc CertEnumCertificatesInStore*(hCertStore: CertStore, pPrevCertContext: PCCertContext): pointer
#
# proc CertFreeCertificateContext*(pContext: PCCertContext): bool
#
# proc CertCloseStore*(hCertStore:CertStore, flags:cint): bool
#
# {.pop.}
|