...

Source file src/github.com/google/certificate-transparency-go/gossip/minimal/x509ext/x509ext_test.go

Documentation: github.com/google/certificate-transparency-go/gossip/minimal/x509ext

     1  // Copyright 2018 Google LLC. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package x509ext_test
    16  
    17  import (
    18  	"encoding/hex"
    19  	"encoding/pem"
    20  	"fmt"
    21  	"strings"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
    26  	"github.com/google/certificate-transparency-go/tls"
    27  	"github.com/google/certificate-transparency-go/x509"
    28  	"github.com/google/certificate-transparency-go/x509/pkix"
    29  
    30  	ct "github.com/google/certificate-transparency-go"
    31  )
    32  
    33  var (
    34  	// pilotPubKeyPEM is the public key for Google's Pilot log.
    35  	pilotPubKeyPEM = []byte(`-----BEGIN PUBLIC KEY-----
    36  MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHT
    37  DM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==
    38  -----END PUBLIC KEY-----`)
    39  )
    40  
    41  func TestSTHFromCert(t *testing.T) {
    42  	rawPubKey, _ := pem.Decode(pilotPubKeyPEM)
    43  	pubKey, _, _, err := ct.PublicKeyFromPEM(pilotPubKeyPEM)
    44  	if err != nil {
    45  		t.Fatalf("failed to decode test pubkey data: %v", err)
    46  	}
    47  	validSTH := x509ext.LogSTHInfo{
    48  		LogURL:    []byte("http://ct.example.com/log"),
    49  		Version:   0,
    50  		TreeSize:  7834120,
    51  		Timestamp: 1519395540364,
    52  		SHA256RootHash: [...]byte{
    53  			0xfe, 0xc0, 0xed, 0xe1, 0xbe, 0xf1, 0xa2, 0x25, 0xc3, 0x72, 0xa6, 0x44, 0x1b, 0xa2, 0xd5, 0xdd, 0x3b, 0xbb, 0x9b, 0x7b, 0xa9, 0x79, 0xd1, 0xa7, 0x03, 0xe7, 0xfe, 0x81, 0x49, 0x75, 0x85, 0xfb,
    54  		},
    55  		TreeHeadSignature: ct.DigitallySigned{
    56  			Algorithm: tls.SignatureAndHashAlgorithm{Hash: tls.SHA256, Signature: tls.ECDSA},
    57  			Signature: dehex("220164e031604aa2a0b68887ba668cefb3e0046e455d6323c3df38b8d50108895d70220146199ee1d759a029d8b37ce8701d2ca47a387bad8ac8ef1cb84b77bc0820ed"),
    58  		},
    59  	}
    60  	sthData, err := tls.Marshal(validSTH)
    61  	if err != nil {
    62  		t.Fatalf("failed to marshal STH: %v", err)
    63  	}
    64  
    65  	var tests = []struct {
    66  		name    string
    67  		cert    x509.Certificate
    68  		wantErr string
    69  	}{
    70  		{
    71  			name: "ValidSTH",
    72  			cert: x509.Certificate{
    73  				NotBefore:               time.Now(),
    74  				NotAfter:                time.Now().Add(24 * time.Hour),
    75  				PublicKey:               pubKey,
    76  				RawSubjectPublicKeyInfo: rawPubKey.Bytes,
    77  				Subject: pkix.Name{
    78  					CommonName: "Test STH holder",
    79  				},
    80  				Extensions: []pkix.Extension{
    81  					{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: sthData},
    82  				},
    83  			},
    84  		},
    85  		{
    86  			name: "MissingSTH",
    87  			cert: x509.Certificate{
    88  				NotBefore: time.Now(),
    89  				NotAfter:  time.Now().Add(24 * time.Hour),
    90  				Subject: pkix.Name{
    91  					CommonName: "Test STH holder",
    92  				},
    93  			},
    94  			wantErr: "no STH extension found",
    95  		},
    96  		{
    97  			name: "TrailingData",
    98  			cert: x509.Certificate{
    99  				NotBefore: time.Now(),
   100  				NotAfter:  time.Now().Add(24 * time.Hour),
   101  				Subject: pkix.Name{
   102  					CommonName: "Test STH holder",
   103  				},
   104  				Extensions: []pkix.Extension{
   105  					{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: append(sthData, 0xff)},
   106  				},
   107  			},
   108  			wantErr: "trailing data",
   109  		},
   110  		{
   111  			name: "InvalidSTH",
   112  			cert: x509.Certificate{
   113  				NotBefore: time.Now(),
   114  				NotAfter:  time.Now().Add(24 * time.Hour),
   115  				Subject: pkix.Name{
   116  					CommonName: "Test STH holder",
   117  				},
   118  				Extensions: []pkix.Extension{
   119  					{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: []byte{0xff}},
   120  				},
   121  			},
   122  			wantErr: "failed to unmarshal",
   123  		},
   124  	}
   125  
   126  	for _, test := range tests {
   127  		t.Run(test.name, func(t *testing.T) {
   128  			got, err := x509ext.STHFromCert(&test.cert)
   129  			if err != nil {
   130  				if test.wantErr == "" {
   131  					t.Errorf("STHFromCert(%+v)=nil,%v; want _,nil", test.cert, err)
   132  				} else if !strings.Contains(err.Error(), test.wantErr) {
   133  					t.Errorf("STHFromCert(%+v)=nil,%v; want nil,err containing %q", test.cert, err, test.wantErr)
   134  				}
   135  				return
   136  			}
   137  			if test.wantErr != "" {
   138  				t.Errorf("STHFromCert(%+v)=_,nil; want nil,err containing %q", test.cert, test.wantErr)
   139  			}
   140  			t.Logf("retrieved STH %+v", got)
   141  		})
   142  	}
   143  }
   144  
   145  func dehex(h string) []byte {
   146  	d, err := hex.DecodeString(h)
   147  	if err != nil {
   148  		panic(fmt.Sprintf("hard-coded data %q failed to decode! %v", h, err))
   149  	}
   150  	return d
   151  }
   152  

View as plain text