ssl_certs.nim 5.1 KB

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