forked from TrueCloudLab/certificates
Move subject, issuer and serial number.
This commit is contained in:
parent
8069d1246b
commit
abaaec04f1
3 changed files with 151 additions and 143 deletions
|
@ -4,9 +4,7 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -139,144 +137,3 @@ func CreateCertificate(template, parent *x509.Certificate, pub crypto.PublicKey,
|
||||||
}
|
}
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name is the JSON representation of X.501 type Name, used in the X.509 subject
|
|
||||||
// and issuer fields.
|
|
||||||
type Name struct {
|
|
||||||
Country MultiString `json:"country"`
|
|
||||||
Organization MultiString `json:"organization"`
|
|
||||||
OrganizationalUnit MultiString `json:"organizationUnit"`
|
|
||||||
Locality MultiString `json:"locality"`
|
|
||||||
Province MultiString `json:"province"`
|
|
||||||
StreetAddress MultiString `json:"streetAddress"`
|
|
||||||
PostalCode MultiString `json:"postalCode"`
|
|
||||||
SerialNumber string `json:"serialNumber"`
|
|
||||||
CommonName string `json:"commonName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON
|
|
||||||
// object in the Subject struct or a string as just the subject common name.
|
|
||||||
func (n *Name) UnmarshalJSON(data []byte) error {
|
|
||||||
if cn, ok := maybeString(data); ok {
|
|
||||||
n.CommonName = cn
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type nameAlias Name
|
|
||||||
var nn nameAlias
|
|
||||||
if err := json.Unmarshal(data, &nn); err != nil {
|
|
||||||
return errors.Wrap(err, "error unmarshaling json")
|
|
||||||
}
|
|
||||||
*n = Name(nn)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subject is the JSON representation of the X.509 subject field.
|
|
||||||
type Subject Name
|
|
||||||
|
|
||||||
func newSubject(n pkix.Name) Subject {
|
|
||||||
return Subject{
|
|
||||||
Country: n.Country,
|
|
||||||
Organization: n.Organization,
|
|
||||||
OrganizationalUnit: n.OrganizationalUnit,
|
|
||||||
Locality: n.Locality,
|
|
||||||
Province: n.Province,
|
|
||||||
StreetAddress: n.StreetAddress,
|
|
||||||
PostalCode: n.PostalCode,
|
|
||||||
SerialNumber: n.SerialNumber,
|
|
||||||
CommonName: n.CommonName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the subject in the given certificate.
|
|
||||||
func (s Subject) Set(c *x509.Certificate) {
|
|
||||||
c.Subject = pkix.Name{
|
|
||||||
Country: s.Country,
|
|
||||||
Organization: s.Organization,
|
|
||||||
OrganizationalUnit: s.OrganizationalUnit,
|
|
||||||
Locality: s.Locality,
|
|
||||||
Province: s.Province,
|
|
||||||
StreetAddress: s.StreetAddress,
|
|
||||||
PostalCode: s.PostalCode,
|
|
||||||
SerialNumber: s.SerialNumber,
|
|
||||||
CommonName: s.CommonName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issuer is the JSON representation of the X.509 issuer field.
|
|
||||||
type Issuer Name
|
|
||||||
|
|
||||||
func newIssuer(n pkix.Name) Issuer {
|
|
||||||
return Issuer{
|
|
||||||
Country: n.Country,
|
|
||||||
Organization: n.Organization,
|
|
||||||
OrganizationalUnit: n.OrganizationalUnit,
|
|
||||||
Locality: n.Locality,
|
|
||||||
Province: n.Province,
|
|
||||||
StreetAddress: n.StreetAddress,
|
|
||||||
PostalCode: n.PostalCode,
|
|
||||||
SerialNumber: n.SerialNumber,
|
|
||||||
CommonName: n.CommonName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the issuer in the given certificate.
|
|
||||||
func (i Issuer) Set(c *x509.Certificate) {
|
|
||||||
c.Issuer = pkix.Name{
|
|
||||||
Country: i.Country,
|
|
||||||
Organization: i.Organization,
|
|
||||||
OrganizationalUnit: i.OrganizationalUnit,
|
|
||||||
Locality: i.Locality,
|
|
||||||
Province: i.Province,
|
|
||||||
StreetAddress: i.StreetAddress,
|
|
||||||
PostalCode: i.PostalCode,
|
|
||||||
SerialNumber: i.SerialNumber,
|
|
||||||
CommonName: i.CommonName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerialNumber is the JSON representation of the X509 serial number.
|
|
||||||
type SerialNumber struct {
|
|
||||||
*big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the serial number in the given certificate.
|
|
||||||
func (s SerialNumber) Set(c *x509.Certificate) {
|
|
||||||
c.SerialNumber = s.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SerialNumber) MarshalJSON() ([]byte, error) {
|
|
||||||
if s == nil || s.Int == nil {
|
|
||||||
return []byte(`null`), nil
|
|
||||||
}
|
|
||||||
return s.Int.MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals an
|
|
||||||
// integer or a string into a serial number. If a string is used, a prefix of
|
|
||||||
// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8, and “0x” or
|
|
||||||
// “0X” selects base 16. Otherwise, the selected base is 10 and no prefix is
|
|
||||||
// accepted.
|
|
||||||
func (s *SerialNumber) UnmarshalJSON(data []byte) error {
|
|
||||||
if sn, ok := maybeString(data); ok {
|
|
||||||
// Using base 0 to accept prefixes 0b, 0o, 0x but defaults as base 10.
|
|
||||||
b, ok := new(big.Int).SetString(sn, 0)
|
|
||||||
if !ok {
|
|
||||||
return errors.Errorf("error unmarshaling json: serialNumber %s is not valid", sn)
|
|
||||||
}
|
|
||||||
*s = SerialNumber{
|
|
||||||
Int: b,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume a number.
|
|
||||||
var i int64
|
|
||||||
if err := json.Unmarshal(data, &i); err != nil {
|
|
||||||
return errors.Wrap(err, "error unmarshaling json")
|
|
||||||
}
|
|
||||||
*s = SerialNumber{
|
|
||||||
Int: new(big.Int).SetInt64(i),
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -373,3 +374,49 @@ func (n NameConstraints) Set(c *x509.Certificate) {
|
||||||
c.PermittedURIDomains = n.PermittedURIDomains
|
c.PermittedURIDomains = n.PermittedURIDomains
|
||||||
c.ExcludedURIDomains = n.ExcludedURIDomains
|
c.ExcludedURIDomains = n.ExcludedURIDomains
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SerialNumber is the JSON representation of the X509 serial number.
|
||||||
|
type SerialNumber struct {
|
||||||
|
*big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the serial number in the given certificate.
|
||||||
|
func (s SerialNumber) Set(c *x509.Certificate) {
|
||||||
|
c.SerialNumber = s.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SerialNumber) MarshalJSON() ([]byte, error) {
|
||||||
|
if s == nil || s.Int == nil {
|
||||||
|
return []byte(`null`), nil
|
||||||
|
}
|
||||||
|
return s.Int.MarshalJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals an
|
||||||
|
// integer or a string into a serial number. If a string is used, a prefix of
|
||||||
|
// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8, and “0x” or
|
||||||
|
// “0X” selects base 16. Otherwise, the selected base is 10 and no prefix is
|
||||||
|
// accepted.
|
||||||
|
func (s *SerialNumber) UnmarshalJSON(data []byte) error {
|
||||||
|
if sn, ok := maybeString(data); ok {
|
||||||
|
// Using base 0 to accept prefixes 0b, 0o, 0x but defaults as base 10.
|
||||||
|
b, ok := new(big.Int).SetString(sn, 0)
|
||||||
|
if !ok {
|
||||||
|
return errors.Errorf("error unmarshaling json: serialNumber %s is not valid", sn)
|
||||||
|
}
|
||||||
|
*s = SerialNumber{
|
||||||
|
Int: b,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume a number.
|
||||||
|
var i int64
|
||||||
|
if err := json.Unmarshal(data, &i); err != nil {
|
||||||
|
return errors.Wrap(err, "error unmarshaling json")
|
||||||
|
}
|
||||||
|
*s = SerialNumber{
|
||||||
|
Int: new(big.Int).SetInt64(i),
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
104
x509util/pkix.go
Normal file
104
x509util/pkix.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package x509util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Name is the JSON representation of X.501 type Name, used in the X.509 subject
|
||||||
|
// and issuer fields.
|
||||||
|
type Name struct {
|
||||||
|
Country MultiString `json:"country"`
|
||||||
|
Organization MultiString `json:"organization"`
|
||||||
|
OrganizationalUnit MultiString `json:"organizationUnit"`
|
||||||
|
Locality MultiString `json:"locality"`
|
||||||
|
Province MultiString `json:"province"`
|
||||||
|
StreetAddress MultiString `json:"streetAddress"`
|
||||||
|
PostalCode MultiString `json:"postalCode"`
|
||||||
|
SerialNumber string `json:"serialNumber"`
|
||||||
|
CommonName string `json:"commonName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshal interface and unmarshals a JSON
|
||||||
|
// object in the Subject struct or a string as just the subject common name.
|
||||||
|
func (n *Name) UnmarshalJSON(data []byte) error {
|
||||||
|
if cn, ok := maybeString(data); ok {
|
||||||
|
n.CommonName = cn
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type nameAlias Name
|
||||||
|
var nn nameAlias
|
||||||
|
if err := json.Unmarshal(data, &nn); err != nil {
|
||||||
|
return errors.Wrap(err, "error unmarshaling json")
|
||||||
|
}
|
||||||
|
*n = Name(nn)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subject is the JSON representation of the X.509 subject field.
|
||||||
|
type Subject Name
|
||||||
|
|
||||||
|
func newSubject(n pkix.Name) Subject {
|
||||||
|
return Subject{
|
||||||
|
Country: n.Country,
|
||||||
|
Organization: n.Organization,
|
||||||
|
OrganizationalUnit: n.OrganizationalUnit,
|
||||||
|
Locality: n.Locality,
|
||||||
|
Province: n.Province,
|
||||||
|
StreetAddress: n.StreetAddress,
|
||||||
|
PostalCode: n.PostalCode,
|
||||||
|
SerialNumber: n.SerialNumber,
|
||||||
|
CommonName: n.CommonName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the subject in the given certificate.
|
||||||
|
func (s Subject) Set(c *x509.Certificate) {
|
||||||
|
c.Subject = pkix.Name{
|
||||||
|
Country: s.Country,
|
||||||
|
Organization: s.Organization,
|
||||||
|
OrganizationalUnit: s.OrganizationalUnit,
|
||||||
|
Locality: s.Locality,
|
||||||
|
Province: s.Province,
|
||||||
|
StreetAddress: s.StreetAddress,
|
||||||
|
PostalCode: s.PostalCode,
|
||||||
|
SerialNumber: s.SerialNumber,
|
||||||
|
CommonName: s.CommonName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issuer is the JSON representation of the X.509 issuer field.
|
||||||
|
type Issuer Name
|
||||||
|
|
||||||
|
func newIssuer(n pkix.Name) Issuer {
|
||||||
|
return Issuer{
|
||||||
|
Country: n.Country,
|
||||||
|
Organization: n.Organization,
|
||||||
|
OrganizationalUnit: n.OrganizationalUnit,
|
||||||
|
Locality: n.Locality,
|
||||||
|
Province: n.Province,
|
||||||
|
StreetAddress: n.StreetAddress,
|
||||||
|
PostalCode: n.PostalCode,
|
||||||
|
SerialNumber: n.SerialNumber,
|
||||||
|
CommonName: n.CommonName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the issuer in the given certificate.
|
||||||
|
func (i Issuer) Set(c *x509.Certificate) {
|
||||||
|
c.Issuer = pkix.Name{
|
||||||
|
Country: i.Country,
|
||||||
|
Organization: i.Organization,
|
||||||
|
OrganizationalUnit: i.OrganizationalUnit,
|
||||||
|
Locality: i.Locality,
|
||||||
|
Province: i.Province,
|
||||||
|
StreetAddress: i.StreetAddress,
|
||||||
|
PostalCode: i.PostalCode,
|
||||||
|
SerialNumber: i.SerialNumber,
|
||||||
|
CommonName: i.CommonName,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue