ssl_certs.nim 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. from os import existsEnv, getEnv
  14. import strutils
  15. # SECURITY: this unnecessarily scans through dirs/files regardless of the
  16. # actual host OS/distribution. Hopefully all the paths are writeble only by
  17. # root.
  18. # FWIW look for files before scanning entire dirs.
  19. const certificate_paths = [
  20. # Debian, Ubuntu, Arch: maintained by update-ca-certificates, SUSE, Gentoo
  21. # NetBSD (security/mozilla-rootcerts)
  22. # SLES10/SLES11, https://golang.org/issue/12139
  23. "/etc/ssl/certs/ca-certificates.crt",
  24. # OpenSUSE
  25. "/etc/ssl/ca-bundle.pem",
  26. # Red Hat 5+, Fedora, Centos
  27. "/etc/pki/tls/certs/ca-bundle.crt",
  28. # Red Hat 4
  29. "/usr/share/ssl/certs/ca-bundle.crt",
  30. # FreeBSD (security/ca-root-nss package)
  31. "/usr/local/share/certs/ca-root-nss.crt",
  32. # CentOS/RHEL 7
  33. "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
  34. # OpenBSD, FreeBSD (optional symlink)
  35. "/etc/ssl/cert.pem",
  36. # Mac OS X
  37. "/System/Library/OpenSSL/certs/cert.pem",
  38. # Fedora/RHEL
  39. "/etc/pki/tls/certs",
  40. # Android
  41. "/system/etc/security/cacerts",
  42. # FreeBSD
  43. "/usr/local/share/certs",
  44. # NetBSD
  45. "/etc/openssl/certs",
  46. ]
  47. when defined(haiku):
  48. const
  49. B_FIND_PATH_EXISTING_ONLY = 0x4
  50. B_FIND_PATH_DATA_DIRECTORY = 6
  51. proc find_paths_etc(architecture: cstring, baseDirectory: cint,
  52. subPath: cstring, flags: uint32,
  53. paths: var ptr UncheckedArray[cstring],
  54. pathCount: var csize): int32
  55. {.importc, header: "<FindDirectory.h>".}
  56. proc free(p: pointer) {.importc, header: "<stdlib.h>".}
  57. iterator scanSSLCertificates*(useEnvVars = false): string =
  58. ## Scan for SSL/TLS CA certificates on disk.
  59. ##
  60. ## if `useEnvVars` is true, the SSL_CERT_FILE and SSL_CERT_DIR
  61. ## environment variables can be used to override the certificate
  62. ## directories to scan or specify a CA certificate file.
  63. if existsEnv("SSL_CERT_FILE"):
  64. yield getEnv("SSL_CERT_FILE")
  65. elif existsEnv("SSL_CERT_DIR"):
  66. let p = getEnv("SSL_CERT_DIR")
  67. for fn in joinPath(p, "*").walkFiles():
  68. yield fn
  69. else:
  70. when not defined(haiku):
  71. for p in certificate_paths:
  72. if p.endsWith(".pem") or p.endsWith(".crt"):
  73. if fileExists(p):
  74. yield p
  75. elif dirExists(p):
  76. for fn in joinPath(p, "*").walkFiles():
  77. yield fn
  78. else:
  79. var
  80. paths: ptr UncheckedArray[cstring]
  81. size: csize
  82. let err = find_paths_etc(
  83. nil, B_FIND_PATH_DATA_DIRECTORY, "ssl/CARootCertificates.pem",
  84. B_FIND_PATH_EXISTING_ONLY, paths, size
  85. )
  86. if err == 0:
  87. defer: free(paths)
  88. for i in 0 ..< size:
  89. yield $paths[i]
  90. # Certificates management on windows
  91. # when defined(windows) or defined(nimdoc):
  92. #
  93. # import openssl
  94. #
  95. # type
  96. # PCCertContext {.final, pure.} = pointer
  97. # X509 {.final, pure.} = pointer
  98. # CertStore {.final, pure.} = pointer
  99. #
  100. # # OpenSSL cert store
  101. #
  102. # {.push stdcall, dynlib: "kernel32", importc.}
  103. #
  104. # proc CertOpenSystemStore*(hprov: pointer=nil, szSubsystemProtocol: cstring): CertStore
  105. #
  106. # proc CertEnumCertificatesInStore*(hCertStore: CertStore, pPrevCertContext: PCCertContext): pointer
  107. #
  108. # proc CertFreeCertificateContext*(pContext: PCCertContext): bool
  109. #
  110. # proc CertCloseStore*(hCertStore:CertStore, flags:cint): bool
  111. #
  112. # {.pop.}