This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-04-07
Channels
- # babashka (31)
- # babashka-sci-dev (10)
- # beginners (64)
- # biff (11)
- # clerk (5)
- # cljdoc (2)
- # clojure (84)
- # clojure-boston (3)
- # clojure-conj (2)
- # clojure-europe (11)
- # data-science (19)
- # datomic (118)
- # fulcro (3)
- # graalvm (3)
- # hoplon (6)
- # inf-clojure (146)
- # instaparse (5)
- # lsp (13)
- # malli (3)
- # off-topic (13)
- # pedestal (5)
- # proletarian (5)
- # re-frame (14)
- # reitit (12)
- # releases (1)
- # ring (19)
- # scittle (2)
- # shadow-cljs (155)
- # slack-help (3)
Hey friends, I've found myself putting bb on more and more Windows computers in my job role as a sysadmin. So, rather than just pulling the binary from GitHub every time, I wrote a little install script. For now it just supports downloading to a specific directory or to program files
and puts the babashka dir on the path.
https://github.com/mjhika/babashka-dl
Great job! We can link to this project from the babashka README - or if the script matures, maybe we can just put it into babashka's repo eventually
Sure! I'd love to mature the script some more so that it has much more feature parity
i noticed that CertificateFactory is not in babashka. is that on purpose? is there a better way to create an X509Certificate from a file?
user=> (import java.security.cert.X509Certificate)
java.security.cert.X509Certificate
user=> (import java.security.cert.CertificateFactory)
java.lang.Exception: Unable to resolve classname: java.security.cert.CertificateFactory [at <repl>:2:2]
user=>
This code is know to work in bb: https://github.com/gnarroway/hato/blob/7862f9e3ab692ea499b935842978688831e61bfd/src/hato/client.clj#L79-L125
@UDXEK491P What is the context of your question? I think we could add support for this to bb but it would be good to know more about the why
i am writing a script to automate some cert management for my team. it comes split apart and i need to assemble it in a specific order so i want to parse the certs. basically the flow is zip -> cert -> chained cert -> install into gcp
it would be useful to know what more you need after adding this class. would it be possible to give a full example? then I'll make sure it will work with bb
sure, this is what i'm working with at the moment
(ns certificate
(:import
(java.time.format DateTimeFormatter)
(java.security.cert X509Certificate CertificateFactory))
(:require
[ :as io]
[com.stuartsierra.dependency :as dep]
[clojure.string :as str]))
(defn x509-certificate
^X509Certificate
[f]
(let [input (io/input-stream f)
factory (CertificateFactory/getInstance "X.509")]
(.generateCertificate factory input)))
(defn not-before
[certificate]
(.toInstant (.getNotBefore certificate)))
(defn not-after
[certificate]
(.toInstant (.getNotAfter certificate)))
(defn valid-dates
[certificate]
((juxt not-before not-after) certificate))
(defn issuer
[certificate]
(.getName (.getIssuerX500Principal certificate)))
(defn subject
[certificate]
(.getName (.getSubjectX500Principal certificate)))
(defn subject-alternative-names
[certificate]
(.getIssuerAlternativeNames certificate))
(defn chain-sort-step
[graph current others]
(reduce (fn [graph other]
(if (= (issuer current) (subject other))
(dep/depend graph current other)
graph))
graph
others))
(defn chain-sort
[certificates]
(let [certs (set certificates)]
(dep/topo-sort
(reduce (fn [graph cert] (chain-sort-step graph cert (disj certs cert)))
(dep/graph)
certs))))
;; Text Utils for working with X.509 principal strings
(defn common-name
[string]
(second (re-find #"CN=(?<name>\S+)" string)))
(defn- inst->iso-date-string
[instant]
(let [formatter (.withZone DateTimeFormatter/BASIC_ISO_DATE (java.time.ZoneId/of "UTC"))]
(.format formatter instant)))
probably won't need all those functions in the end since they are more exploratory. but the key ones are x509-certificate
and chain-sort
something like this would demo it
(chain-sort
[(x509-certificate "child.crt")
(x509-certificate "root.crt")])
i think being able to just create an instance of X509Certificate form the CertificateFactory would be sufficient though. since the rest of the code definitely works in bb
@UDXEK491P what OS are you on?
if m1, you can download a binary from here:
https://cirrus-ci.com/task/5896904853159936
to test with.
Note that you need to do sudo xattr -c ~/path/to/bb
to clear some quarantaine stuff after downloading.
ran into
clojure.lang.ExceptionInfo: Method getSubjectX500Principal on class sun.security.x509.X509CertImpl not allowed! [at <repl>:26:1]
(import java.security.cert.X509Certificate)
(import java.security.cert.CertificateFactory)
(require '[ :as io])
(defn x509-certificate
^X509Certificate
[f]
(let [input (io/input-stream f)
factory (CertificateFactory/getInstance "X.509")]
(.generateCertificate factory input)))
(def cert (x509-certificate (io/file "certificate.crt")))
(.getSubjectX500Principal cert)
in jvm clojure
user=>
(import java.security.cert.X509Certificate)
(import java.security.cert.CertificateFactory)
(require '[ :as io])
(defn x509-certificate
^X509Certificate
[f]
(let [input (io/input-stream f)
factory (CertificateFactory/getInstance "X.509")]
(.generateCertificate factory input)))
java.security.cert.X509Certificate
user=> java.security.cert.CertificateFactory
user=> nil
user=> #'user/x509-certificate
user=> (def cert (x509-certificate (io/file "clojure.crt")))
#'user/cert
user=> (.getSubjectX500Principal cert)
#object[javax.security.auth.x500.X500Principal 0x344426bf "CN="]
Thanks. A workaround for now:
(prn (let [^X509Certificate cert cert]
(.getSubjectX500Principal cert)))
The type inference in bb isn't so great, but I'll push a fix so it will work without this workaround
ok, try this binary, it should work with your previous code: https://cirrus-ci.com/task/5336053058371584