|
@@ -49,20 +49,20 @@ type CertificateIdentity struct {
|
|
|
|
|
|
// CertificateNetwork bundles a network ID with the fingerprint of its primary controller.
|
|
|
type CertificateNetwork struct {
|
|
|
- ID uint64 `json:"id"`
|
|
|
- Controller Fingerprint `json:"controller"`
|
|
|
+ ID uint64 `json:"id"`
|
|
|
+ Controller Fingerprint `json:"controller"`
|
|
|
}
|
|
|
|
|
|
// CertificateSubject contains information about the subject of a certificate.
|
|
|
type CertificateSubject struct {
|
|
|
- Timestamp int64 `json:"timestamp"`
|
|
|
- Identities []CertificateIdentity `json:"identities,omitempty"`
|
|
|
- Networks []CertificateNetwork `json:"networks,omitempty"`
|
|
|
- Certificates [][CertificateSerialNoSize]byte `json:"certificates,omitempty"`
|
|
|
- UpdateURLs []string `json:"updateURLs,omitempty"`
|
|
|
- Name CertificateName `json:"name"`
|
|
|
- UniqueID []byte `json:"uniqueId,omitempty"`
|
|
|
- UniqueIDProofSignature []byte `json:"uniqueIdProofSignature,omitempty"`
|
|
|
+ Timestamp int64 `json:"timestamp"`
|
|
|
+ Identities []CertificateIdentity `json:"identities,omitempty"`
|
|
|
+ Networks []CertificateNetwork `json:"networks,omitempty"`
|
|
|
+ Certificates [][]byte `json:"certificates,omitempty"`
|
|
|
+ UpdateURLs []string `json:"updateURLs,omitempty"`
|
|
|
+ Name CertificateName `json:"name"`
|
|
|
+ UniqueID []byte `json:"uniqueId,omitempty"`
|
|
|
+ UniqueIDProofSignature []byte `json:"uniqueIdProofSignature,omitempty"`
|
|
|
}
|
|
|
|
|
|
// Certificate is a Go reflection of the C ZT_Certificate struct.
|
|
@@ -79,25 +79,30 @@ type Certificate struct {
|
|
|
Signature []byte `json:"signature,omitempty"`
|
|
|
}
|
|
|
|
|
|
-type cCertificate struct {
|
|
|
- C C.ZT_Certificate
|
|
|
+type CCertificate struct {
|
|
|
+ C unsafe.Pointer
|
|
|
+ internalCertificate C.ZT_Certificate
|
|
|
internalSubjectIdentities []C.ZT_Certificate_Identity
|
|
|
internalSubjectNetworks []C.ZT_Certificate_Network
|
|
|
- internalSubjectUpdateURLs []*C.char
|
|
|
+ internalSubjectCertificates []uintptr
|
|
|
+ internalSubjectUpdateURLs []uintptr
|
|
|
internalSubjectUpdateURLsData [][]byte
|
|
|
}
|
|
|
|
|
|
-// newCertificateFromCCertificate translates a C ZT_Certificate into a Go Certificate.
|
|
|
-func newCertificateFromCCertificate(cc *C.ZT_Certificate) *Certificate {
|
|
|
+// NewCertificateFromCCertificate translates a C ZT_Certificate into a Go Certificate.
|
|
|
+func NewCertificateFromCCertificate(ccptr unsafe.Pointer) *Certificate {
|
|
|
+ cc := (*C.ZT_Certificate)(ccptr)
|
|
|
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
|
|
|
+ sn := (*[48]byte)(unsafe.Pointer(&cc.serialNo[0]))[:]
|
|
|
+ if !allZero(sn) {
|
|
|
+ var tmp [48]byte
|
|
|
+ copy(tmp[:], sn)
|
|
|
+ c.SerialNo = tmp[:]
|
|
|
}
|
|
|
c.Flags = uint64(cc.flags)
|
|
|
c.Timestamp = int64(cc.timestamp)
|
|
@@ -135,14 +140,16 @@ func newCertificateFromCCertificate(cc *C.ZT_Certificate) *Certificate {
|
|
|
return nil
|
|
|
}
|
|
|
c.Subject.Networks = append(c.Subject.Networks, CertificateNetwork{
|
|
|
- ID: uint64(cn.id),
|
|
|
+ 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)
|
|
|
+ csn := *((**[48]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(cc.subject.certificates)) + (uintptr(i) * pointerSize))))
|
|
|
+ var tmp [48]byte
|
|
|
+ copy(tmp[:], csn[:])
|
|
|
+ c.Subject.Certificates = append(c.Subject.Certificates, tmp[:])
|
|
|
}
|
|
|
|
|
|
for i := 0; i < int(cc.subject.updateURLCount); i++ {
|
|
@@ -204,26 +211,36 @@ func newCertificateFromCCertificate(cc *C.ZT_Certificate) *Certificate {
|
|
|
return c
|
|
|
}
|
|
|
|
|
|
-// cCertificate creates a C ZT_Certificate structure from the content of a Certificate.
|
|
|
+// 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
|
|
|
// 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
|
|
|
-// them up automatically when cCertificate is released. Only the 'C' field
|
|
|
-// in cCertificate should be directly used.
|
|
|
-func (c *Certificate) cCertificate() *cCertificate {
|
|
|
- var cc cCertificate
|
|
|
+// them up automatically when CCertificate is released. Only the 'C' field
|
|
|
+// in CCertificate should be directly used. The rest are internal and are
|
|
|
+// hidden outside the package.
|
|
|
+//
|
|
|
+// Ensure that Certificate is not modified until the generated C certificate
|
|
|
+// is no longer in use.
|
|
|
+func (c *Certificate) CCertificate() *CCertificate {
|
|
|
+ var cc CCertificate
|
|
|
+ var ccC *C.ZT_Certificate
|
|
|
+
|
|
|
+ cc.C = unsafe.Pointer(&cc.internalCertificate)
|
|
|
+ ccC = &cc.internalCertificate
|
|
|
|
|
|
if len(c.SerialNo) == 48 {
|
|
|
- copy((*[48]byte)(unsafe.Pointer(&cc.C.serialNo[0]))[:], c.SerialNo[:])
|
|
|
+ copy((*[48]byte)(unsafe.Pointer(&ccC.serialNo[0]))[:], c.SerialNo)
|
|
|
}
|
|
|
- cc.C.flags = C.uint64_t(c.Flags)
|
|
|
- cc.C.timestamp = C.int64_t(c.Timestamp)
|
|
|
- cc.C.validity[0] = C.int64_t(c.Validity[0])
|
|
|
- cc.C.validity[1] = C.int64_t(c.Validity[1])
|
|
|
+ ccC.flags = C.uint64_t(c.Flags)
|
|
|
+ ccC.timestamp = C.int64_t(c.Timestamp)
|
|
|
+ ccC.validity[0] = C.int64_t(c.Validity[0])
|
|
|
+ ccC.validity[1] = C.int64_t(c.Validity[1])
|
|
|
|
|
|
- cc.C.subject.timestamp = C.int64_t(c.Subject.Timestamp)
|
|
|
+ ccC.subject.timestamp = C.int64_t(c.Subject.Timestamp)
|
|
|
|
|
|
if len(c.Subject.Identities) > 0 {
|
|
|
cc.internalSubjectIdentities = make([]C.ZT_Certificate_Identity, len(c.Subject.Identities))
|
|
@@ -236,8 +253,8 @@ func (c *Certificate) cCertificate() *cCertificate {
|
|
|
cc.internalSubjectIdentities[i].locator = id.Locator.cl
|
|
|
}
|
|
|
}
|
|
|
- cc.C.subject.identities = &cc.internalSubjectIdentities[0]
|
|
|
- cc.C.subject.identityCount = C.uint(len(c.Subject.Identities))
|
|
|
+ ccC.subject.identities = &cc.internalSubjectIdentities[0]
|
|
|
+ ccC.subject.identityCount = C.uint(len(c.Subject.Identities))
|
|
|
}
|
|
|
|
|
|
if len(c.Subject.Networks) > 0 {
|
|
@@ -249,45 +266,52 @@ func (c *Certificate) cCertificate() *cCertificate {
|
|
|
copy((*[48]byte)(unsafe.Pointer(&cc.internalSubjectNetworks[i].controller.hash[0]))[:], n.Controller.Hash)
|
|
|
}
|
|
|
}
|
|
|
- cc.C.subject.networks = &cc.internalSubjectNetworks[0]
|
|
|
- cc.C.subject.networkCount = C.uint(len(c.Subject.Networks))
|
|
|
+ ccC.subject.networks = &cc.internalSubjectNetworks[0]
|
|
|
+ ccC.subject.networkCount = C.uint(len(c.Subject.Networks))
|
|
|
}
|
|
|
|
|
|
if len(c.Subject.Certificates) > 0 {
|
|
|
- cc.C.subject.certificates = (**C.uint8_t)(unsafe.Pointer(&c.Subject.Certificates[0]))
|
|
|
- cc.C.subject.certificateCount = C.uint(len(c.Subject.Certificates))
|
|
|
+ cc.internalSubjectCertificates = make([]uintptr, len(c.Subject.Certificates))
|
|
|
+ for i, cert := range c.Subject.Certificates {
|
|
|
+ if len(cert) != 48 {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ cc.internalSubjectCertificates[i] = uintptr(unsafe.Pointer(&cert[0]))
|
|
|
+ }
|
|
|
+ ccC.subject.certificates = (**C.uint8_t)(unsafe.Pointer(&cc.internalSubjectCertificates[0]))
|
|
|
+ ccC.subject.certificateCount = C.uint(len(c.Subject.Certificates))
|
|
|
}
|
|
|
|
|
|
if len(c.Subject.UpdateURLs) > 0 {
|
|
|
- cc.internalSubjectUpdateURLs = make([]*C.char, len(c.Subject.UpdateURLs))
|
|
|
+ cc.internalSubjectUpdateURLs = make([]uintptr, len(c.Subject.UpdateURLs))
|
|
|
cc.internalSubjectUpdateURLsData = make([][]byte, len(c.Subject.UpdateURLs))
|
|
|
for i, u := range c.Subject.UpdateURLs {
|
|
|
cc.internalSubjectUpdateURLsData[i] = stringAsZeroTerminatedBytes(u)
|
|
|
- cc.internalSubjectUpdateURLs[i] = (*C.char)(unsafe.Pointer(&cc.internalSubjectUpdateURLsData[0]))
|
|
|
+ cc.internalSubjectUpdateURLs[i] = uintptr(unsafe.Pointer(&cc.internalSubjectUpdateURLsData[0][0]))
|
|
|
}
|
|
|
- cc.C.subject.updateURLs = (**C.char)(unsafe.Pointer(&cc.internalSubjectUpdateURLs[0]))
|
|
|
- cc.C.subject.updateURLCount = C.uint(len(c.Subject.UpdateURLs))
|
|
|
+ ccC.subject.updateURLs = (**C.char)(unsafe.Pointer(&cc.internalSubjectUpdateURLs[0]))
|
|
|
+ ccC.subject.updateURLCount = C.uint(len(c.Subject.UpdateURLs))
|
|
|
}
|
|
|
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.serialNo[0]), CertificateMaxStringLength+1, c.Subject.Name.SerialNo)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.commonName[0]), CertificateMaxStringLength+1, c.Subject.Name.CommonName)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.country[0]), CertificateMaxStringLength+1, c.Subject.Name.Country)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.organization[0]), CertificateMaxStringLength+1, c.Subject.Name.Organization)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.unit[0]), CertificateMaxStringLength+1, c.Subject.Name.Unit)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.locality[0]), CertificateMaxStringLength+1, c.Subject.Name.Locality)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.province[0]), CertificateMaxStringLength+1, c.Subject.Name.Province)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.streetAddress[0]), CertificateMaxStringLength+1, c.Subject.Name.StreetAddress)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.postalCode[0]), CertificateMaxStringLength+1, c.Subject.Name.PostalCode)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.email[0]), CertificateMaxStringLength+1, c.Subject.Name.Email)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.url[0]), CertificateMaxStringLength+1, c.Subject.Name.URL)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.subject.name.host[0]), CertificateMaxStringLength+1, c.Subject.Name.Host)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.serialNo[0]), CertificateMaxStringLength+1, c.Subject.Name.SerialNo)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.commonName[0]), CertificateMaxStringLength+1, c.Subject.Name.CommonName)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.country[0]), CertificateMaxStringLength+1, c.Subject.Name.Country)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.organization[0]), CertificateMaxStringLength+1, c.Subject.Name.Organization)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.unit[0]), CertificateMaxStringLength+1, c.Subject.Name.Unit)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.locality[0]), CertificateMaxStringLength+1, c.Subject.Name.Locality)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.province[0]), CertificateMaxStringLength+1, c.Subject.Name.Province)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.streetAddress[0]), CertificateMaxStringLength+1, c.Subject.Name.StreetAddress)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.postalCode[0]), CertificateMaxStringLength+1, c.Subject.Name.PostalCode)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.email[0]), CertificateMaxStringLength+1, c.Subject.Name.Email)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.url[0]), CertificateMaxStringLength+1, c.Subject.Name.URL)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.subject.name.host[0]), CertificateMaxStringLength+1, c.Subject.Name.Host)
|
|
|
|
|
|
if len(c.Subject.UniqueID) > 0 {
|
|
|
- cc.C.subject.uniqueId = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueID[0]))
|
|
|
- cc.C.subject.uniqueIdSize = C.uint(len(c.Subject.UniqueID))
|
|
|
+ ccC.subject.uniqueId = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueID[0]))
|
|
|
+ ccC.subject.uniqueIdSize = C.uint(len(c.Subject.UniqueID))
|
|
|
if len(c.Subject.UniqueIDProofSignature) > 0 {
|
|
|
- cc.C.subject.uniqueIdProofSignature = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueIDProofSignature[0]))
|
|
|
- cc.C.subject.uniqueIdProofSignatureSize = C.uint(len(c.Subject.UniqueIDProofSignature))
|
|
|
+ ccC.subject.uniqueIdProofSignature = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueIDProofSignature[0]))
|
|
|
+ ccC.subject.uniqueIdProofSignatureSize = C.uint(len(c.Subject.UniqueIDProofSignature))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -295,32 +319,32 @@ func (c *Certificate) cCertificate() *cCertificate {
|
|
|
if !c.Issuer.initCIdentityPtr() {
|
|
|
return nil
|
|
|
}
|
|
|
- cc.C.issuer = c.Issuer.cid
|
|
|
+ ccC.issuer = c.Issuer.cid
|
|
|
}
|
|
|
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.serialNo[0]), CertificateMaxStringLength+1, c.IssuerName.SerialNo)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.commonName[0]), CertificateMaxStringLength+1, c.IssuerName.CommonName)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.country[0]), CertificateMaxStringLength+1, c.IssuerName.Country)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.organization[0]), CertificateMaxStringLength+1, c.IssuerName.Organization)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.unit[0]), CertificateMaxStringLength+1, c.IssuerName.Unit)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.locality[0]), CertificateMaxStringLength+1, c.IssuerName.Locality)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.province[0]), CertificateMaxStringLength+1, c.IssuerName.Province)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.streetAddress[0]), CertificateMaxStringLength+1, c.IssuerName.StreetAddress)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.postalCode[0]), CertificateMaxStringLength+1, c.IssuerName.PostalCode)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.email[0]), CertificateMaxStringLength+1, c.IssuerName.Email)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.url[0]), CertificateMaxStringLength+1, c.IssuerName.URL)
|
|
|
- cStrCopy(unsafe.Pointer(&cc.C.issuerName.host[0]), CertificateMaxStringLength+1, c.IssuerName.Host)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.serialNo[0]), CertificateMaxStringLength+1, c.IssuerName.SerialNo)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.commonName[0]), CertificateMaxStringLength+1, c.IssuerName.CommonName)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.country[0]), CertificateMaxStringLength+1, c.IssuerName.Country)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.organization[0]), CertificateMaxStringLength+1, c.IssuerName.Organization)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.unit[0]), CertificateMaxStringLength+1, c.IssuerName.Unit)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.locality[0]), CertificateMaxStringLength+1, c.IssuerName.Locality)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.province[0]), CertificateMaxStringLength+1, c.IssuerName.Province)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.streetAddress[0]), CertificateMaxStringLength+1, c.IssuerName.StreetAddress)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.postalCode[0]), CertificateMaxStringLength+1, c.IssuerName.PostalCode)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.email[0]), CertificateMaxStringLength+1, c.IssuerName.Email)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.url[0]), CertificateMaxStringLength+1, c.IssuerName.URL)
|
|
|
+ cStrCopy(unsafe.Pointer(&ccC.issuerName.host[0]), CertificateMaxStringLength+1, c.IssuerName.Host)
|
|
|
|
|
|
if len(c.ExtendedAttributes) > 0 {
|
|
|
- cc.C.extendedAttributes = (*C.uint8_t)(unsafe.Pointer(&c.ExtendedAttributes[0]))
|
|
|
- cc.C.extendedAttributesSize = C.uint(len(c.ExtendedAttributes))
|
|
|
+ ccC.extendedAttributes = (*C.uint8_t)(unsafe.Pointer(&c.ExtendedAttributes[0]))
|
|
|
+ ccC.extendedAttributesSize = C.uint(len(c.ExtendedAttributes))
|
|
|
}
|
|
|
|
|
|
- cc.C.maxPathLength = C.uint(c.MaxPathLength)
|
|
|
+ ccC.maxPathLength = C.uint(c.MaxPathLength)
|
|
|
|
|
|
if len(c.Signature) > 0 {
|
|
|
- cc.C.signature = (*C.uint8_t)(unsafe.Pointer(&c.Signature[0]))
|
|
|
- cc.C.signatureSize = C.uint(len(c.Signature))
|
|
|
+ ccC.signature = (*C.uint8_t)(unsafe.Pointer(&c.Signature[0]))
|
|
|
+ ccC.signatureSize = C.uint(len(c.Signature))
|
|
|
}
|
|
|
|
|
|
return &cc
|