Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / crypto / tls / ca_set.go
blobfe2a540f4dbc5e768a8b2a3c60b2c6adcb42c5fe
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package tls
7 import (
8 "crypto/x509"
9 "encoding/pem"
10 "strings"
13 // A CASet is a set of certificates.
14 type CASet struct {
15 bySubjectKeyId map[string][]*x509.Certificate
16 byName map[string][]*x509.Certificate
19 func NewCASet() *CASet {
20 return &CASet{
21 make(map[string][]*x509.Certificate),
22 make(map[string][]*x509.Certificate),
26 func nameToKey(name *x509.Name) string {
27 return strings.Join(name.Country, ",") + "/" + strings.Join(name.Organization, ",") + "/" + strings.Join(name.OrganizationalUnit, ",") + "/" + name.CommonName
30 // FindVerifiedParent attempts to find the certificate in s which has signed
31 // the given certificate. If no such certificate can be found or the signature
32 // doesn't match, it returns nil.
33 func (s *CASet) FindVerifiedParent(cert *x509.Certificate) (parent *x509.Certificate) {
34 var candidates []*x509.Certificate
36 if len(cert.AuthorityKeyId) > 0 {
37 candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
39 if len(candidates) == 0 {
40 candidates = s.byName[nameToKey(&cert.Issuer)]
43 for _, c := range candidates {
44 if cert.CheckSignatureFrom(c) == nil {
45 return c
49 return nil
52 // AddCert adds a certificate to the set
53 func (s *CASet) AddCert(cert *x509.Certificate) {
54 if len(cert.SubjectKeyId) > 0 {
55 keyId := string(cert.SubjectKeyId)
56 s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], cert)
58 name := nameToKey(&cert.Subject)
59 s.byName[name] = append(s.byName[name], cert)
62 // SetFromPEM attempts to parse a series of PEM encoded root certificates. It
63 // appends any certificates found to s and returns true if any certificates
64 // were successfully parsed. On many Linux systems, /etc/ssl/cert.pem will
65 // contains the system wide set of root CAs in a format suitable for this
66 // function.
67 func (s *CASet) SetFromPEM(pemCerts []byte) (ok bool) {
68 for len(pemCerts) > 0 {
69 var block *pem.Block
70 block, pemCerts = pem.Decode(pemCerts)
71 if block == nil {
72 break
74 if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
75 continue
78 cert, err := x509.ParseCertificate(block.Bytes)
79 if err != nil {
80 continue
83 s.AddCert(cert)
84 ok = true
87 return