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.
13 // A CASet is a set of certificates.
15 bySubjectKeyId
map[string][]*x509
.Certificate
16 byName
map[string][]*x509
.Certificate
19 func NewCASet() *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 {
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
67 func (s
*CASet
) SetFromPEM(pemCerts
[]byte) (ok
bool) {
68 for len(pemCerts
) > 0 {
70 block
, pemCerts
= pem
.Decode(pemCerts
)
74 if block
.Type
!= "CERTIFICATE" ||
len(block
.Headers
) != 0 {
78 cert
, err
:= x509
.ParseCertificate(block
.Bytes
)