oidPostalCode = []int{2, 5, 4, 17}
)
-func (n Name) toRDNSequence() (ret rdnSequence) {
- ret = make([]relativeDistinguishedNameSET, 9 /* maximum number of elements */ )
- i := 0
- if len(n.Country) > 0 {
- ret[i] = []attributeTypeAndValue{{oidCountry, n.Country}}
- i++
- }
- if len(n.Organization) > 0 {
- ret[i] = []attributeTypeAndValue{{oidOrganization, n.Organization}}
- i++
+// appendRDNs appends a relativeDistinguishedNameSET to the given rdnSequence
+// and returns the new value. The relativeDistinguishedNameSET contains an
+// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
+// search for AttributeTypeAndValue.
+func appendRDNs(in rdnSequence, values []string, oid asn1.ObjectIdentifier) rdnSequence {
+ if len(values) == 0 {
+ return in
}
- if len(n.OrganizationalUnit) > 0 {
- ret[i] = []attributeTypeAndValue{{oidOrganizationalUnit, n.OrganizationalUnit}}
- i++
+
+ s := make([]attributeTypeAndValue, len(values))
+ for i, value := range values {
+ s[i].Type = oid
+ s[i].Value = value
}
+
+ return append(in, s)
+}
+
+func (n Name) toRDNSequence() (ret rdnSequence) {
+ ret = appendRDNs(ret, n.Country, oidCountry)
+ ret = appendRDNs(ret, n.Organization, oidOrganization)
+ ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
+ ret = appendRDNs(ret, n.Locality, oidLocatity)
+ ret = appendRDNs(ret, n.Province, oidProvince)
+ ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
+ ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
if len(n.CommonName) > 0 {
- ret[i] = []attributeTypeAndValue{{oidCommonName, n.CommonName}}
- i++
+ ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
}
if len(n.SerialNumber) > 0 {
- ret[i] = []attributeTypeAndValue{{oidSerialNumber, n.SerialNumber}}
- i++
+ ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
}
- if len(n.Locality) > 0 {
- ret[i] = []attributeTypeAndValue{{oidLocatity, n.Locality}}
- i++
- }
- if len(n.Province) > 0 {
- ret[i] = []attributeTypeAndValue{{oidProvince, n.Province}}
- i++
- }
- if len(n.StreetAddress) > 0 {
- ret[i] = []attributeTypeAndValue{{oidStreetAddress, n.StreetAddress}}
- i++
- }
- if len(n.PostalCode) > 0 {
- ret[i] = []attributeTypeAndValue{{oidPostalCode, n.PostalCode}}
- i++
- }
-
- // Adding another RDN here? Remember to update the maximum number of
- // elements in the make() at the top of the function.
- return ret[0:i]
+ return ret
}
func getSignatureAlgorithmFromOID(oid []int) SignatureAlgorithm {
// Subject Alternate Name values
DNSNames []string
EmailAddresses []string
+
+ PolicyIdentifiers []asn1.ObjectIdentifier
}
// UnsupportedAlgorithmError results from attempting to perform an operation
E int
}
+// RFC 5280 4.2.1.4
+type policyInformation struct {
+ Policy asn1.ObjectIdentifier
+ // policyQualifiers omitted
+}
+
func parsePublicKey(algo PublicKeyAlgorithm, asn1Data []byte) (interface{}, os.Error) {
switch algo {
case RSA:
return nil, err
}
- out.Version = in.TBSCertificate.Version
+ out.Version = in.TBSCertificate.Version + 1
out.SerialNumber = in.TBSCertificate.SerialNumber.Bytes
out.Issuer.fillFromRDNSequence(&in.TBSCertificate.Issuer)
out.Subject.fillFromRDNSequence(&in.TBSCertificate.Subject)
}
out.SubjectKeyId = keyid
continue
+
+ case 32:
+ // RFC 5280 4.2.1.4: Certificate Policies
+ var policies []policyInformation
+ if _, err = asn1.Unmarshal(e.Value, &policies); err != nil {
+ return nil, err
+ }
+ out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies))
+ for i, policy := range policies {
+ out.PolicyIdentifiers[i] = policy.Policy
+ }
}
}
}
var (
- oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
- oidExtensionKeyUsage = []int{2, 5, 29, 15}
- oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
- oidExtensionBasicConstraints = []int{2, 5, 29, 19}
- oidExtensionSubjectAltName = []int{2, 5, 29, 17}
+ oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
+ oidExtensionKeyUsage = []int{2, 5, 29, 15}
+ oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
+ oidExtensionBasicConstraints = []int{2, 5, 29, 19}
+ oidExtensionSubjectAltName = []int{2, 5, 29, 17}
+ oidExtensionCertificatePolicies = []int{2, 5, 29, 32}
)
func buildExtensions(template *Certificate) (ret []extension, err os.Error) {
- ret = make([]extension, 5 /* maximum number of elements. */ )
+ ret = make([]extension, 6 /* maximum number of elements. */ )
n := 0
if template.KeyUsage != 0 {
n++
}
+ if len(template.PolicyIdentifiers) > 0 {
+ ret[n].Id = oidExtensionCertificatePolicies
+ policies := make([]policyInformation, len(template.PolicyIdentifiers))
+ for i, policy := range template.PolicyIdentifiers {
+ policies[i].Policy = policy
+ }
+ ret[n].Value, err = asn1.Marshal(policies)
+ if err != nil {
+ return
+ }
+ n++
+ }
+
// Adding another extension here? Remember to update the maximum number
// of elements in the make() at the top of the function.
encodedPublicKey := asn1.BitString{BitLength: len(asn1PublicKey) * 8, Bytes: asn1PublicKey}
c := tbsCertificate{
- Version: 3,
+ Version: 2,
SerialNumber: asn1.RawValue{Bytes: template.SerialNumber, Tag: 2},
SignatureAlgorithm: algorithmIdentifier{oidSHA1WithRSA},
Issuer: parent.Subject.toRDNSequence(),