aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-11-05 10:44:37 +0100
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-11-05 10:44:37 +0100
commitaa0c2f3fc07e3c52e62c570ee9108e4602b3ddbf (patch)
treeb60aeb847ae698dadacb017b7ecf06d51c6c4866
parent53ad91c63c2788a83d0e80985ffa89ce7cdf203f (diff)
simplified encoding and decoding
Go's "encoding/json" already takes care of encoding and decoding byte slices as base64. As such, it need not be done explicitly by us.
-rw-r--r--client/client.go12
-rw-r--r--reqres.go62
-rw-r--r--type.go30
-rw-r--r--x509.go15
4 files changed, 52 insertions, 67 deletions
diff --git a/client/client.go b/client/client.go
index 864afb4..54f75de 100644
--- a/client/client.go
+++ b/client/client.go
@@ -78,10 +78,10 @@ func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StI
return nil, fmt.Errorf("failed marshaling StItem: %v", err)
}
data, err := json.Marshal(stfe.AddEntryRequest{
- Item: base64.StdEncoding.EncodeToString(leaf),
- Signature: base64.StdEncoding.EncodeToString(ed25519.Sign(*c.PrivateKey, leaf)),
+ Item: leaf,
+ Signature: ed25519.Sign(*c.PrivateKey, leaf),
SignatureScheme: uint16(tls.Ed25519),
- Chain: c.b64Chain(),
+ Chain: c.chain(),
})
if err != nil {
return nil, fmt.Errorf("failed creating post data: %v", err)
@@ -189,10 +189,10 @@ func (c *Client) GetAnchors(ctx context.Context, start, end uint64) ([]*x509.Cer
return nil, fmt.Errorf("TODO: Client.GetAnchors()")
}
-func (c *Client) b64Chain() []string {
- chain := make([]string, 0, len(c.Chain))
+func (c *Client) chain() [][]byte {
+ chain := make([][]byte, 0, len(c.Chain))
for _, cert := range c.Chain {
- chain = append(chain, base64.StdEncoding.EncodeToString(cert.Raw))
+ chain = append(chain, cert.Raw)
}
return chain
}
diff --git a/reqres.go b/reqres.go
index 1cad933..0179d1c 100644
--- a/reqres.go
+++ b/reqres.go
@@ -4,23 +4,21 @@ import (
"fmt"
"strconv"
- stdtls "crypto/tls"
+ "crypto/tls"
"crypto/x509"
- "encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
- "github.com/google/certificate-transparency-go/tls"
"github.com/google/trillian"
)
// AddEntryRequest is a collection of add-entry input parameters
type AddEntryRequest struct {
- Item string `json:"item"` // base64-encoded StItem
- Signature string `json:"signature"` // base64-encoded DigitallySigned
- SignatureScheme uint16 `json:"signature_scheme"` // RFC 8446, §4.2.3
- Chain []string `json:"chain"` // base64-encoded X.509 certificates
+ Item []byte `json:"item"` // tls-serialized StItem
+ Signature []byte `json:"signature"` // serialized signature using the signature scheme below
+ SignatureScheme uint16 `json:"signature_scheme"` // rfc 8446, §4.2.3
+ Chain [][]byte `json:"chain"` // der-encoded X.509 certificates
}
// GetEntriesRequest is a collection of get-entry input parameters
@@ -31,8 +29,8 @@ type GetEntriesRequest struct {
// GetProofByHashRequest is a collection of get-proof-by-hash input parameters
type GetProofByHashRequest struct {
- Hash []byte `json:"hash"` // base64-encoded leaf hash
- TreeSize int64 `json:"tree_size"` // Tree head size to base proof on
+ Hash []byte `json:"hash"` // leaf hash
+ TreeSize int64 `json:"tree_size"` // tree head size to base proof on
}
// GetConsistencyProofRequest is a collection of get-consistency-proof input
@@ -44,9 +42,9 @@ type GetConsistencyProofRequest struct {
// GetEntryResponse is an assembled log entry and its associated appendix
type GetEntryResponse struct {
- Leaf string `json:"leaf"` // base64-encoded StItem
- Signature string `json:"signature"` // base64-encoded signature
- Chain []string `json:"chain"` // base64-encoded X.509 certificates
+ Leaf []byte `json:"leaf"` // tls-serialized StItem
+ Signature []byte `json:"signature"` // Serialized signature using the log's signature scheme
+ Chain [][]byte `json:"chain"` // der-encoded certificates
}
// NewAddEntryRequest parses and sanitizes the JSON-encoded add-entry
@@ -60,36 +58,26 @@ func NewAddEntryRequest(lp *LogParameters, r *http.Request) ([]byte, []byte, err
}
var item StItem
- if err := item.UnmarshalB64(entry.Item); err != nil {
+ if err := item.Unmarshal(entry.Item); err != nil {
return nil, nil, fmt.Errorf("StItem(%s): %v", item.Format, err)
}
if item.Format != StFormatChecksumV1 {
return nil, nil, fmt.Errorf("invalid StItem format: %s", item.Format)
} // note that decode would have failed if invalid checksum/package length
- chain, err := buildChainFromB64List(lp, entry.Chain)
+ chain, err := buildChainFromDerList(lp, entry.Chain)
if err != nil {
return nil, nil, fmt.Errorf("invalid certificate chain: %v", err)
} // the final entry in chain is a valid trust anchor
-
- signature, err := base64.StdEncoding.DecodeString(entry.Signature)
- if err != nil {
- return nil, nil, fmt.Errorf("invalid signature encoding: %v", err)
- }
- serialized, err := tls.Marshal(item)
- if err != nil {
- return nil, nil, fmt.Errorf("failed tls marshaling StItem(%s): %v", item.Format, err)
- }
- if err := verifySignature(lp, chain[0], stdtls.SignatureScheme(entry.SignatureScheme), serialized, signature); err != nil {
+ if err := verifySignature(lp, chain[0], tls.SignatureScheme(entry.SignatureScheme), entry.Item, entry.Signature); err != nil {
return nil, nil, fmt.Errorf("invalid signature: %v", err)
}
- extra, err := NewAppendix(chain, signature, entry.SignatureScheme).Marshal()
+ extra, err := NewAppendix(chain, entry.Signature, entry.SignatureScheme).Marshal()
if err != nil {
return nil, nil, fmt.Errorf("failed marshaling appendix: %v", err)
}
-
- return serialized, extra, nil
+ return entry.Item, extra, nil
}
// NewGetEntriesRequest parses and sanitizes the URL-encoded get-entries
@@ -129,7 +117,7 @@ func NewGetProofByHashRequest(httpRequest *http.Request) (GetProofByHashRequest,
return GetProofByHashRequest{}, fmt.Errorf("bad tree_size parameter: negative value")
}
- hash, err := base64.StdEncoding.DecodeString(httpRequest.FormValue("hash"))
+ hash, err := deb64(httpRequest.FormValue("hash"))
if err != nil {
return GetProofByHashRequest{}, fmt.Errorf("bad hash parameter: %v", err)
}
@@ -162,17 +150,11 @@ func NewGetEntryResponse(leaf, appendix []byte) (GetEntryResponse, error) {
if err := app.Unmarshal(appendix); err != nil {
return GetEntryResponse{}, err
}
-
- chain := make([]string, 0, len(app.Chain))
+ chain := make([][]byte, 0, len(app.Chain))
for _, c := range app.Chain {
- chain = append(chain, base64.StdEncoding.EncodeToString(c.Data))
+ chain = append(chain, c.Data)
}
-
- return GetEntryResponse{
- Leaf: base64.StdEncoding.EncodeToString(leaf),
- Signature: base64.StdEncoding.EncodeToString(app.Signature),
- Chain: chain,
- }, nil
+ return GetEntryResponse{leaf, app.Signature, chain}, nil
}
// NewGetEntriesResponse assembles a get-entries response
@@ -188,10 +170,10 @@ func NewGetEntriesResponse(leaves []*trillian.LogLeaf) ([]GetEntryResponse, erro
return entries, nil
}
-func NewGetAnchorsResponse(anchors []*x509.Certificate) []string {
- certificates := make([]string, 0, len(anchors))
+func NewGetAnchorsResponse(anchors []*x509.Certificate) [][]byte {
+ certificates := make([][]byte, 0, len(anchors))
for _, certificate := range anchors {
- certificates = append(certificates, base64.StdEncoding.EncodeToString(certificate.Raw))
+ certificates = append(certificates, certificate.Raw)
}
return certificates
}
diff --git a/type.go b/type.go
index 20042a8..037cedb 100644
--- a/type.go
+++ b/type.go
@@ -133,37 +133,37 @@ func (i StItem) String() string {
}
func (i SignedTreeHeadV1) String() string {
- return fmt.Sprintf("LogId(%s) TreeHead(%s) Signature(%s)", base64.StdEncoding.EncodeToString(i.LogId), i.TreeHead, base64.StdEncoding.EncodeToString(i.Signature))
+ return fmt.Sprintf("LogId(%s) TreeHead(%s) Signature(%s)", b64(i.LogId), i.TreeHead, b64(i.Signature))
}
func (i SignedDebugInfoV1) String() string {
- return fmt.Sprintf("LogId(%s) Message(%s) Signature(%s)", base64.StdEncoding.EncodeToString(i.LogId), string(i.Message), base64.StdEncoding.EncodeToString(i.Signature))
+ return fmt.Sprintf("LogId(%s) Message(%s) Signature(%s)", b64(i.LogId), string(i.Message), b64(i.Signature))
}
func (i ConsistencyProofV1) String() string {
path := make([]string, 0, len(i.ConsistencyPath))
for _, hash := range i.ConsistencyPath {
- path = append(path, base64.StdEncoding.EncodeToString(hash.Data))
+ path = append(path, b64(hash.Data))
}
- return fmt.Sprintf("LogID(%s) TreeSize1(%d) TreeSize2(%d) ConsistencyPath(%v)", base64.StdEncoding.EncodeToString(i.LogId), i.TreeSize1, i.TreeSize2, path)
+ return fmt.Sprintf("LogID(%s) TreeSize1(%d) TreeSize2(%d) ConsistencyPath(%v)", b64(i.LogId), i.TreeSize1, i.TreeSize2, path)
}
func (i InclusionProofV1) String() string {
path := make([]string, 0, len(i.InclusionPath))
for _, hash := range i.InclusionPath {
- path = append(path, base64.StdEncoding.EncodeToString(hash.Data))
+ path = append(path, b64(hash.Data))
}
- return fmt.Sprintf("LogID(%s) TreeSize(%d) LeafIndex(%d) AuditPath(%v)", base64.StdEncoding.EncodeToString(i.LogId), i.TreeSize, i.LeafIndex, path)
+ return fmt.Sprintf("LogID(%s) TreeSize(%d) LeafIndex(%d) AuditPath(%v)", b64(i.LogId), i.TreeSize, i.LeafIndex, path)
}
func (i ChecksumV1) String() string {
- return fmt.Sprintf("Package(%s) Checksum(%s)", string(i.Package), base64.StdEncoding.EncodeToString(i.Checksum))
+ return fmt.Sprintf("Package(%s) Checksum(%s)", string(i.Package), b64(i.Checksum))
}
func (th TreeHeadV1) String() string {
- return fmt.Sprintf("Timestamp(%s) TreeSize(%d) RootHash(%s)", time.Unix(int64(th.Timestamp/1000), 0), th.TreeSize, base64.StdEncoding.EncodeToString(th.RootHash.Data))
+ return fmt.Sprintf("Timestamp(%s) TreeSize(%d) RootHash(%s)", time.Unix(int64(th.Timestamp/1000), 0), th.TreeSize, b64(th.RootHash.Data))
}
// Marshal serializes an Stitem as defined by RFC 5246
@@ -181,7 +181,7 @@ func (i *StItem) MarshalB64() (string, error) {
if err != nil {
return "", err
}
- return base64.StdEncoding.EncodeToString(serialized), nil
+ return b64(serialized), nil
}
// Unmarshal unpacks a serialized StItem
@@ -197,7 +197,7 @@ func (i *StItem) Unmarshal(serialized []byte) error {
// UnmarshalB64 unpacks a base64-encoded serialized StItem
func (i *StItem) UnmarshalB64(s string) error {
- serialized, err := base64.StdEncoding.DecodeString(s)
+ serialized, err := deb64(s)
if err != nil {
return fmt.Errorf("base64 decoding failed for StItem(%s): %v", i.Format, err)
}
@@ -213,7 +213,7 @@ func (a *Appendix) Marshal() ([]byte, error) {
return serialized, nil
}
-// Unmarshal unpacks an serialized Appendix
+// Unmarshal unpacks a serialized Appendix
func (a *Appendix) Unmarshal(serialized []byte) error {
extra, err := tls.Unmarshal(serialized, a)
if err != nil {
@@ -336,3 +336,11 @@ func NewAppendix(x509Chain []*x509.Certificate, signature []byte, signatureSchem
SignatureScheme: signatureScheme,
}
}
+
+func b64(b []byte) string {
+ return base64.StdEncoding.EncodeToString(b)
+}
+
+func deb64(str string) ([]byte, error) {
+ return base64.StdEncoding.DecodeString(str)
+}
diff --git a/x509.go b/x509.go
index e0fa3bc..db983c4 100644
--- a/x509.go
+++ b/x509.go
@@ -8,7 +8,6 @@ import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
- "encoding/base64"
"encoding/pem"
"io/ioutil"
)
@@ -135,17 +134,13 @@ func ParseChain(rest []byte) ([]*x509.Certificate, error) {
return chain, nil
}
-// ParseB64Chain parses a list of base64 DER-encoded X.509 certificates, such
+// ParseDerChain parses a list of base64 DER-encoded X.509 certificates, such
// that the first (zero-index) string is interpretted as an end-entity
// certificate and the remaining ones as the an intermediate CertPool.
-func ParseB64Chain(chain []string) (*x509.Certificate, *x509.CertPool, error) {
+func ParseDerChain(chain [][]byte) (*x509.Certificate, *x509.CertPool, error) {
var certificate *x509.Certificate
intermediatePool := x509.NewCertPool()
- for index, cert := range chain {
- der, err := base64.StdEncoding.DecodeString(cert)
- if err != nil {
- return nil, nil, fmt.Errorf("certificate decoding failed: %v", err)
- }
+ for index, der := range chain {
c, err := x509.ParseCertificate(der)
if err != nil {
return nil, nil, fmt.Errorf("certificate decoding failed: %v", err)
@@ -163,8 +158,8 @@ func ParseB64Chain(chain []string) (*x509.Certificate, *x509.CertPool, error) {
return certificate, intermediatePool, nil
}
-func buildChainFromB64List(lp *LogParameters, b64chain []string) ([]*x509.Certificate, error) {
- certificate, intermediatePool, err := ParseB64Chain(b64chain)
+func buildChainFromDerList(lp *LogParameters, derChain [][]byte) ([]*x509.Certificate, error) {
+ certificate, intermediatePool, err := ParseDerChain(derChain)
if err != nil {
return nil, err
}