mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
More cert Go plumbing.
This commit is contained in:
parent
0d764f5a3d
commit
7b869684c6
3 changed files with 148 additions and 9 deletions
|
@ -25,6 +25,7 @@ const (
|
||||||
CertificateMaxStringLength = int(C.ZT_CERTIFICATE_MAX_STRING_LENGTH)
|
CertificateMaxStringLength = int(C.ZT_CERTIFICATE_MAX_STRING_LENGTH)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CertificateName identifies a real-world entity that owns a subject or has signed a certificate.
|
||||||
type CertificateName struct {
|
type CertificateName struct {
|
||||||
SerialNo string `json:"serialNo,omitempty"`
|
SerialNo string `json:"serialNo,omitempty"`
|
||||||
CommonName string `json:"commonName,omitempty"`
|
CommonName string `json:"commonName,omitempty"`
|
||||||
|
@ -40,16 +41,19 @@ type CertificateName struct {
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateIdentity bundles an identity with an optional locator.
|
||||||
type CertificateIdentity struct {
|
type CertificateIdentity struct {
|
||||||
Identity *Identity `json:"identity"`
|
Identity *Identity `json:"identity"`
|
||||||
Locator *Locator `json:"locator,omitempty"`
|
Locator *Locator `json:"locator,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateNetwork bundles a network ID with the fingerprint of its primary controller.
|
||||||
type CertificateNetwork struct {
|
type CertificateNetwork struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id"`
|
||||||
Controller *Fingerprint `json:"controller"`
|
Controller Fingerprint `json:"controller"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateSubject contains information about the subject of a certificate.
|
||||||
type CertificateSubject struct {
|
type CertificateSubject struct {
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
Identities []CertificateIdentity `json:"identities,omitempty"`
|
Identities []CertificateIdentity `json:"identities,omitempty"`
|
||||||
|
@ -61,6 +65,7 @@ type CertificateSubject struct {
|
||||||
UniqueIDProofSignature []byte `json:"uniqueIdProofSignature,omitempty"`
|
UniqueIDProofSignature []byte `json:"uniqueIdProofSignature,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Certificate is a Go reflection of the C ZT_Certificate struct.
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
SerialNo []byte `json:"serialNo,omitempty"`
|
SerialNo []byte `json:"serialNo,omitempty"`
|
||||||
Flags uint64 `json:"flags"`
|
Flags uint64 `json:"flags"`
|
||||||
|
@ -82,11 +87,130 @@ type cCertificate struct {
|
||||||
internalSubjectUpdateURLsData [][]byte
|
internalSubjectUpdateURLsData [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// cCertificate creates a C ZT_Certificate structure
|
// newCertificateFromCCertificate translates a C ZT_Certificate into a Go Certificate.
|
||||||
|
func newCertificateFromCCertificate(cc *C.ZT_Certificate) *Certificate {
|
||||||
|
c := new(Certificate)
|
||||||
|
|
||||||
|
if cc == nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
c.SerialNo = C.GoBytes(unsafe.Pointer(&cc.serialNo[0]), 48)
|
||||||
|
if allZero(c.SerialNo) {
|
||||||
|
c.SerialNo = nil
|
||||||
|
}
|
||||||
|
c.Flags = uint64(cc.flags)
|
||||||
|
c.Timestamp = int64(cc.timestamp)
|
||||||
|
c.Validity[0] = int64(cc.validity[0])
|
||||||
|
c.Validity[1] = int64(cc.validity[1])
|
||||||
|
|
||||||
|
c.Subject.Timestamp = int64(cc.subject.timestamp)
|
||||||
|
|
||||||
|
for i := 0; i < int(cc.subject.identityCount); i++ {
|
||||||
|
cid := (*C.ZT_Certificate_Identity)(unsafe.Pointer(uintptr(unsafe.Pointer(cc.subject.identities)) + (uintptr(C.sizeof_ZT_Certificate_Identity) * uintptr(i))))
|
||||||
|
if cid.identity == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
id, err := newIdentityFromCIdentity(cid.identity)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var loc *Locator
|
||||||
|
if cid.locator != nil {
|
||||||
|
loc, err = newLocatorFromCLocator(cid.locator)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Subject.Identities = append(c.Subject.Identities, CertificateIdentity{
|
||||||
|
Identity: id,
|
||||||
|
Locator: loc,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(cc.subject.networkCount); i++ {
|
||||||
|
cn := (*C.ZT_Certificate_Network)(unsafe.Pointer(uintptr(unsafe.Pointer(cc.subject.networks)) + (uintptr(C.sizeof_ZT_Certificate_Network) * uintptr(i))))
|
||||||
|
fp := newFingerprintFromCFingerprint(&cn.controller)
|
||||||
|
if fp == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.Subject.Networks = append(c.Subject.Networks, CertificateNetwork{
|
||||||
|
ID: uint64(cn.id),
|
||||||
|
Controller: *fp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(cc.subject.certificateCount); i++ {
|
||||||
|
csn := (*[48]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(cc.subject.certificates)) + (uintptr(i) * pointerSize)))
|
||||||
|
c.Subject.Certificates = append(c.Subject.Certificates, *csn)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(cc.subject.updateURLCount); i++ {
|
||||||
|
curl := *((**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cc.subject.updateURLs)) + (uintptr(i) * pointerSize))))
|
||||||
|
c.Subject.UpdateURLs = append(c.Subject.UpdateURLs, C.GoString(curl))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Subject.Name.SerialNo = C.GoString(&cc.subject.name.serialNo[0])
|
||||||
|
c.Subject.Name.CommonName = C.GoString(&cc.subject.name.commonName[0])
|
||||||
|
c.Subject.Name.Country = C.GoString(&cc.subject.name.country[0])
|
||||||
|
c.Subject.Name.Organization = C.GoString(&cc.subject.name.organization[0])
|
||||||
|
c.Subject.Name.Unit = C.GoString(&cc.subject.name.unit[0])
|
||||||
|
c.Subject.Name.Locality = C.GoString(&cc.subject.name.locality[0])
|
||||||
|
c.Subject.Name.Province = C.GoString(&cc.subject.name.province[0])
|
||||||
|
c.Subject.Name.StreetAddress = C.GoString(&cc.subject.name.streetAddress[0])
|
||||||
|
c.Subject.Name.PostalCode = C.GoString(&cc.subject.name.postalCode[0])
|
||||||
|
c.Subject.Name.Email = C.GoString(&cc.subject.name.email[0])
|
||||||
|
c.Subject.Name.URL = C.GoString(&cc.subject.name.url[0])
|
||||||
|
c.Subject.Name.Host = C.GoString(&cc.subject.name.host[0])
|
||||||
|
|
||||||
|
if cc.subject.uniqueIdSize > 0 {
|
||||||
|
c.Subject.UniqueID = C.GoBytes(unsafe.Pointer(cc.subject.uniqueId), C.int(cc.subject.uniqueIdSize))
|
||||||
|
if cc.subject.uniqueIdProofSignatureSize > 0 {
|
||||||
|
c.Subject.UniqueIDProofSignature = C.GoBytes(unsafe.Pointer(cc.subject.uniqueIdProofSignature), C.int(cc.subject.uniqueIdProofSignatureSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cc.issuer != nil {
|
||||||
|
id, err := newIdentityFromCIdentity(cc.issuer)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.Issuer = id
|
||||||
|
}
|
||||||
|
|
||||||
|
c.IssuerName.SerialNo = C.GoString(&cc.issuerName.serialNo[0])
|
||||||
|
c.IssuerName.CommonName = C.GoString(&cc.issuerName.commonName[0])
|
||||||
|
c.IssuerName.Country = C.GoString(&cc.issuerName.country[0])
|
||||||
|
c.IssuerName.Organization = C.GoString(&cc.issuerName.organization[0])
|
||||||
|
c.IssuerName.Unit = C.GoString(&cc.issuerName.unit[0])
|
||||||
|
c.IssuerName.Locality = C.GoString(&cc.issuerName.locality[0])
|
||||||
|
c.IssuerName.Province = C.GoString(&cc.issuerName.province[0])
|
||||||
|
c.IssuerName.StreetAddress = C.GoString(&cc.issuerName.streetAddress[0])
|
||||||
|
c.IssuerName.PostalCode = C.GoString(&cc.issuerName.postalCode[0])
|
||||||
|
c.IssuerName.Email = C.GoString(&cc.issuerName.email[0])
|
||||||
|
c.IssuerName.URL = C.GoString(&cc.issuerName.url[0])
|
||||||
|
c.IssuerName.Host = C.GoString(&cc.issuerName.host[0])
|
||||||
|
|
||||||
|
if cc.extendedAttributesSize > 0 {
|
||||||
|
c.ExtendedAttributes = C.GoBytes(unsafe.Pointer(cc.extendedAttributes), C.int(cc.extendedAttributesSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.MaxPathLength = uint(cc.maxPathLength)
|
||||||
|
|
||||||
|
if cc.signatureSize > 0 {
|
||||||
|
c.Signature = C.GoBytes(unsafe.Pointer(cc.signature), C.int(cc.signatureSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// cCertificate creates a C ZT_Certificate structure from the content of a Certificate.
|
||||||
|
// This will return nil if an error occurs, which would indicate an invalid C
|
||||||
|
// structure or one with invalid values.
|
||||||
// The returned Go structure bundles this with some objects that have
|
// The returned Go structure bundles this with some objects that have
|
||||||
// to be created to set their pointers in ZT_Certificate. It's easier to
|
// to be created to set their pointers in ZT_Certificate. It's easier to
|
||||||
// manage allocation of these in Go and bundle them so Go's GC will clean
|
// manage allocation of these in Go and bundle them so Go's GC will clean
|
||||||
// them up automatically when cCertificate is releaed. Only the 'C' field
|
// them up automatically when cCertificate is released. Only the 'C' field
|
||||||
// in cCertificate should be directly used.
|
// in cCertificate should be directly used.
|
||||||
func (c *Certificate) cCertificate() *cCertificate {
|
func (c *Certificate) cCertificate() *cCertificate {
|
||||||
var cc cCertificate
|
var cc cCertificate
|
||||||
|
|
|
@ -30,6 +30,16 @@ type Locator struct {
|
||||||
cl unsafe.Pointer
|
cl unsafe.Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newLocatorFromCLocator(cl unsafe.Pointer) (*Locator, error) {
|
||||||
|
loc := new(Locator)
|
||||||
|
loc.cl = cl
|
||||||
|
err := loc.init(false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return loc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewLocator(ts int64, endpoints []Endpoint, signer *Identity) (*Locator, error) {
|
func NewLocator(ts int64, endpoints []Endpoint, signer *Identity) (*Locator, error) {
|
||||||
if ts <= 0 || len(endpoints) == 0 || signer == nil {
|
if ts <= 0 || len(endpoints) == 0 || signer == nil {
|
||||||
return nil, ErrInvalidParameter
|
return nil, ErrInvalidParameter
|
||||||
|
@ -46,7 +56,7 @@ func NewLocator(ts int64, endpoints []Endpoint, signer *Identity) (*Locator, err
|
||||||
|
|
||||||
goloc := new(Locator)
|
goloc := new(Locator)
|
||||||
goloc.cl = unsafe.Pointer(loc)
|
goloc.cl = unsafe.Pointer(loc)
|
||||||
return goloc, goloc.init()
|
return goloc, goloc.init(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocatorFromBytes(lb []byte) (*Locator, error) {
|
func NewLocatorFromBytes(lb []byte) (*Locator, error) {
|
||||||
|
@ -60,7 +70,7 @@ func NewLocatorFromBytes(lb []byte) (*Locator, error) {
|
||||||
|
|
||||||
goloc := new(Locator)
|
goloc := new(Locator)
|
||||||
goloc.cl = unsafe.Pointer(loc)
|
goloc.cl = unsafe.Pointer(loc)
|
||||||
return goloc, goloc.init()
|
return goloc, goloc.init(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocatorFromString(s string) (*Locator, error) {
|
func NewLocatorFromString(s string) (*Locator, error) {
|
||||||
|
@ -76,7 +86,7 @@ func NewLocatorFromString(s string) (*Locator, error) {
|
||||||
|
|
||||||
goloc := new(Locator)
|
goloc := new(Locator)
|
||||||
goloc.cl = unsafe.Pointer(loc)
|
goloc.cl = unsafe.Pointer(loc)
|
||||||
return goloc, goloc.init()
|
return goloc, goloc.init(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (loc *Locator) Validate(id *Identity) bool {
|
func (loc *Locator) Validate(id *Identity) bool {
|
||||||
|
@ -116,7 +126,7 @@ func (loc *Locator) UnmarshalJSON(j []byte) error {
|
||||||
return ErrInvalidParameter
|
return ErrInvalidParameter
|
||||||
}
|
}
|
||||||
loc.cl = cl
|
loc.cl = cl
|
||||||
return loc.init()
|
return loc.init(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func locatorFinalizer(obj interface{}) {
|
func locatorFinalizer(obj interface{}) {
|
||||||
|
@ -125,7 +135,7 @@ func locatorFinalizer(obj interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (loc *Locator) init() error {
|
func (loc *Locator) init(requiresDeletion bool) error {
|
||||||
loc.Timestamp = int64(C.ZT_Locator_timestamp(loc.cl))
|
loc.Timestamp = int64(C.ZT_Locator_timestamp(loc.cl))
|
||||||
cfp := C.ZT_Locator_fingerprint(loc.cl)
|
cfp := C.ZT_Locator_fingerprint(loc.cl)
|
||||||
if uintptr(unsafe.Pointer(cfp)) == 0 {
|
if uintptr(unsafe.Pointer(cfp)) == 0 {
|
||||||
|
@ -139,6 +149,8 @@ func (loc *Locator) init() error {
|
||||||
}
|
}
|
||||||
var buf [4096]byte
|
var buf [4096]byte
|
||||||
loc.String = C.GoString(C.ZT_Locator_toString(loc.cl, (*C.char)(unsafe.Pointer(&buf[0])), 4096))
|
loc.String = C.GoString(C.ZT_Locator_toString(loc.cl, (*C.char)(unsafe.Pointer(&buf[0])), 4096))
|
||||||
|
if requiresDeletion {
|
||||||
runtime.SetFinalizer(loc, locatorFinalizer)
|
runtime.SetFinalizer(loc, locatorFinalizer)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ import (
|
||||||
// LogoChar is the unicode character that is ZeroTier's logo
|
// LogoChar is the unicode character that is ZeroTier's logo
|
||||||
const LogoChar = "⏁"
|
const LogoChar = "⏁"
|
||||||
|
|
||||||
|
// pointerSize is the size of a pointer on this system
|
||||||
|
const pointerSize = unsafe.Sizeof(uintptr(0))
|
||||||
|
|
||||||
// Base32StdLowerCase is a base32 encoder/decoder using a lower-case standard alphabet and no padding.
|
// Base32StdLowerCase is a base32 encoder/decoder using a lower-case standard alphabet and no padding.
|
||||||
var Base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
|
var Base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue