summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/tls/ca_set.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/tls/ca_set.go')
-rw-r--r--src/pkg/crypto/tls/ca_set.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/pkg/crypto/tls/ca_set.go b/src/pkg/crypto/tls/ca_set.go
new file mode 100644
index 000000000..e8cddd6f4
--- /dev/null
+++ b/src/pkg/crypto/tls/ca_set.go
@@ -0,0 +1,75 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto/x509";
+ "encoding/pem";
+)
+
+// A CASet is a set of certificates.
+type CASet struct {
+ bySubjectKeyId map[string]*x509.Certificate;
+ byName map[string]*x509.Certificate;
+}
+
+func NewCASet() *CASet {
+ return &CASet{
+ make(map[string]*x509.Certificate),
+ make(map[string]*x509.Certificate),
+ }
+}
+
+func nameToKey(name *x509.Name) string {
+ return name.Country + "/" + name.OrganizationalUnit + "/" + name.OrganizationalUnit + "/" + name.CommonName
+}
+
+// FindParent attempts to find the certificate in s which signs the given
+// certificate. If no such certificate can be found, it returns nil.
+func (s *CASet) FindParent(cert *x509.Certificate) (parent *x509.Certificate) {
+ var ok bool;
+
+ if len(cert.AuthorityKeyId) > 0 {
+ parent, ok = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
+ } else {
+ parent, ok = s.byName[nameToKey(&cert.Issuer)]
+ }
+
+ if !ok {
+ return nil
+ }
+ return parent;
+}
+
+// SetFromPEM attempts to parse a series of PEM encoded root certificates. It
+// appends any certificates found to s and returns true if any certificates
+// were successfully parsed. On many Linux systems, /etc/ssl/cert.pem will
+// contains the system wide set of root CAs in a format suitable for this
+// function.
+func (s *CASet) SetFromPEM(pemCerts []byte) (ok bool) {
+ for len(pemCerts) > 0 {
+ var block *pem.Block;
+ block, pemCerts = pem.Decode(pemCerts);
+ if block == nil {
+ break
+ }
+ if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
+ continue
+ }
+
+ cert, err := x509.ParseCertificate(block.Bytes);
+ if err != nil {
+ continue
+ }
+
+ if len(cert.SubjectKeyId) > 0 {
+ s.bySubjectKeyId[string(cert.SubjectKeyId)] = cert
+ }
+ s.byName[nameToKey(&cert.Subject)] = cert;
+ ok = true;
+ }
+
+ return;
+}