aboutsummaryrefslogtreecommitdiff
path: root/internal/x509util
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus@rgdd.se>2023-12-17 19:10:46 +0100
committerRasmus Dahlberg <rasmus@rgdd.se>2023-12-17 19:10:46 +0100
commit5442e71e7710897126a0034f487fab7e5013b3cc (patch)
tree5fdade10956802b27afa4fcfcfc4b39c3640e137 /internal/x509util
parent895d5fea41177e444c18f4fdc820fffa5f67d5bf (diff)
Drafty server package to receive node requests
curl http://localhost:2009/get-status curl -X POST --data-binary @/home/rgdd/fullchain.pem -u node_a:aaaa http://localhost:2009/add-chain
Diffstat (limited to 'internal/x509util')
-rw-r--r--internal/x509util/x509util.go44
1 files changed, 44 insertions, 0 deletions
diff --git a/internal/x509util/x509util.go b/internal/x509util/x509util.go
new file mode 100644
index 0000000..912d1b4
--- /dev/null
+++ b/internal/x509util/x509util.go
@@ -0,0 +1,44 @@
+package x509util
+
+import (
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+)
+
+// ParseChain parses a certificate chain in PEM format. At least one
+// certificate must be in the chain. The first certificate must be a leaf,
+// whereas all other certificates must CA certificates (intermdiates/roots).
+//
+// Note: it is not checked if the certificate chain's root is trusted or not.
+func ParseChain(b []byte) ([]x509.Certificate, error) {
+ var chain []x509.Certificate
+
+ for {
+ block, rest := pem.Decode(b)
+ if block == nil {
+ break
+ }
+ crt, err := x509.ParseCertificate(block.Bytes)
+ if err != nil {
+ return nil, fmt.Errorf("parse certificate: %v", err)
+ }
+
+ chain = append(chain, *crt)
+ b = rest
+ }
+
+ if len(chain) == 0 {
+ return nil, fmt.Errorf("no certificates in the provided chain")
+ }
+ if chain[0].IsCA {
+ return nil, fmt.Errorf("leaf certificate has the CA bit set")
+ }
+ for _, crt := range chain[1:] {
+ if !crt.IsCA {
+ return nil, fmt.Errorf("non-leaf certificate without the CA bit set")
+ }
+ }
+
+ return chain, nil
+}