blob: 738659011fad129d6e321420d0937c520176a8af [file] [log] [blame]
Adam Langleyc281ddf2011-06-06 10:35:46 -04001// Copyright 2011 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.
4
5// Package pkix contains shared, low level structures used for ASN.1 parsing
6// and serialization of X.509 certificates, CRL and OCSP.
7package pkix
8
9import (
Rob Pike30aa7012011-11-08 15:40:58 -080010 "encoding/asn1"
11 "math/big"
Adam Langleyc281ddf2011-06-06 10:35:46 -040012 "time"
13)
14
15// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
16// 5280, section 4.1.1.2.
17type AlgorithmIdentifier struct {
18 Algorithm asn1.ObjectIdentifier
Russ Cox25733a92011-06-29 09:52:34 -040019 Parameters asn1.RawValue `asn1:"optional"`
Adam Langleyc281ddf2011-06-06 10:35:46 -040020}
21
22type RDNSequence []RelativeDistinguishedNameSET
23
24type RelativeDistinguishedNameSET []AttributeTypeAndValue
25
Adam Langley005686f2012-02-03 15:08:53 -050026// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
27// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
Adam Langleyc281ddf2011-06-06 10:35:46 -040028type AttributeTypeAndValue struct {
29 Type asn1.ObjectIdentifier
30 Value interface{}
31}
32
33// Extension represents the ASN.1 structure of the same name. See RFC
34// 5280, section 4.2.
35type Extension struct {
36 Id asn1.ObjectIdentifier
Russ Cox25733a92011-06-29 09:52:34 -040037 Critical bool `asn1:"optional"`
Adam Langleyc281ddf2011-06-06 10:35:46 -040038 Value []byte
39}
40
41// Name represents an X.509 distinguished name. This only includes the common
42// elements of a DN. Additional elements in the name are ignored.
43type Name struct {
44 Country, Organization, OrganizationalUnit []string
45 Locality, Province []string
46 StreetAddress, PostalCode []string
47 SerialNumber, CommonName string
Adam Langleye74dcbe2011-10-14 15:06:54 -040048
49 Names []AttributeTypeAndValue
Adam Langleyc281ddf2011-06-06 10:35:46 -040050}
51
52func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
53 for _, rdn := range *rdns {
54 if len(rdn) == 0 {
55 continue
56 }
57 atv := rdn[0]
Adam Langleye74dcbe2011-10-14 15:06:54 -040058 n.Names = append(n.Names, atv)
Adam Langleyc281ddf2011-06-06 10:35:46 -040059 value, ok := atv.Value.(string)
60 if !ok {
61 continue
62 }
63
64 t := atv.Type
65 if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
66 switch t[3] {
67 case 3:
68 n.CommonName = value
69 case 5:
70 n.SerialNumber = value
71 case 6:
72 n.Country = append(n.Country, value)
73 case 7:
74 n.Locality = append(n.Locality, value)
75 case 8:
76 n.Province = append(n.Province, value)
77 case 9:
78 n.StreetAddress = append(n.StreetAddress, value)
79 case 10:
80 n.Organization = append(n.Organization, value)
81 case 11:
82 n.OrganizationalUnit = append(n.OrganizationalUnit, value)
83 case 17:
84 n.PostalCode = append(n.PostalCode, value)
85 }
86 }
87 }
88}
89
90var (
91 oidCountry = []int{2, 5, 4, 6}
92 oidOrganization = []int{2, 5, 4, 10}
93 oidOrganizationalUnit = []int{2, 5, 4, 11}
94 oidCommonName = []int{2, 5, 4, 3}
95 oidSerialNumber = []int{2, 5, 4, 5}
96 oidLocality = []int{2, 5, 4, 7}
97 oidProvince = []int{2, 5, 4, 8}
98 oidStreetAddress = []int{2, 5, 4, 9}
99 oidPostalCode = []int{2, 5, 4, 17}
100)
101
102// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
103// and returns the new value. The relativeDistinguishedNameSET contains an
104// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
105// search for AttributeTypeAndValue.
106func appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
107 if len(values) == 0 {
108 return in
109 }
110
111 s := make([]AttributeTypeAndValue, len(values))
112 for i, value := range values {
113 s[i].Type = oid
114 s[i].Value = value
115 }
116
117 return append(in, s)
118}
119
120func (n Name) ToRDNSequence() (ret RDNSequence) {
121 ret = appendRDNs(ret, n.Country, oidCountry)
122 ret = appendRDNs(ret, n.Organization, oidOrganization)
123 ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
124 ret = appendRDNs(ret, n.Locality, oidLocality)
125 ret = appendRDNs(ret, n.Province, oidProvince)
126 ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
127 ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
128 if len(n.CommonName) > 0 {
129 ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
130 }
131 if len(n.SerialNumber) > 0 {
132 ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
133 }
134
135 return ret
136}
137
138// CertificateList represents the ASN.1 structure of the same name. See RFC
139// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
140// signature.
141type CertificateList struct {
142 TBSCertList TBSCertificateList
143 SignatureAlgorithm AlgorithmIdentifier
144 SignatureValue asn1.BitString
145}
146
Russ Cox03823b82011-11-30 12:01:46 -0500147// HasExpired returns true iff now is past the expiry time of certList.
148func (certList *CertificateList) HasExpired(now time.Time) bool {
149 return now.After(certList.TBSCertList.NextUpdate)
Adam Langleyc281ddf2011-06-06 10:35:46 -0400150}
151
152// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
153// 5280, section 5.1.
154type TBSCertificateList struct {
155 Raw asn1.RawContent
Russ Cox25733a92011-06-29 09:52:34 -0400156 Version int `asn1:"optional,default:2"`
Adam Langleyc281ddf2011-06-06 10:35:46 -0400157 Signature AlgorithmIdentifier
158 Issuer RDNSequence
Russ Cox03823b82011-11-30 12:01:46 -0500159 ThisUpdate time.Time
160 NextUpdate time.Time
Russ Cox25733a92011-06-29 09:52:34 -0400161 RevokedCertificates []RevokedCertificate `asn1:"optional"`
162 Extensions []Extension `asn1:"tag:0,optional,explicit"`
Adam Langleyc281ddf2011-06-06 10:35:46 -0400163}
164
165// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
166// 5280, section 5.1.
167type RevokedCertificate struct {
168 SerialNumber *big.Int
Russ Cox03823b82011-11-30 12:01:46 -0500169 RevocationTime time.Time
Russ Cox25733a92011-06-29 09:52:34 -0400170 Extensions []Extension `asn1:"optional"`
Adam Langleyc281ddf2011-06-06 10:35:46 -0400171}