vendor
This commit is contained in:
		
							
								
								
									
										94
									
								
								vendor/github.com/cloudflare/cfssl/auth/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								vendor/github.com/cloudflare/cfssl/auth/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| // Package auth implements an interface for providing CFSSL | ||||
| // authentication. This is meant to authenticate a client CFSSL to a | ||||
| // remote CFSSL in order to prevent unauthorised use of the signature | ||||
| // capabilities. This package provides both the interface and a | ||||
| // standard HMAC-based implementation. | ||||
| package auth | ||||
|  | ||||
| import ( | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/hex" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // An AuthenticatedRequest contains a request and authentication | ||||
| // token. The Provider may determine whether to validate the timestamp | ||||
| // and remote address. | ||||
| type AuthenticatedRequest struct { | ||||
| 	// An Authenticator decides whether to use this field. | ||||
| 	Timestamp     int64  `json:"timestamp,omitempty"` | ||||
| 	RemoteAddress []byte `json:"remote_address,omitempty"` | ||||
| 	Token         []byte `json:"token"` | ||||
| 	Request       []byte `json:"request"` | ||||
| } | ||||
|  | ||||
| // A Provider can generate tokens from a request and verify a | ||||
| // request. The handling of additional authentication data (such as | ||||
| // the IP address) is handled by the concrete type, as is any | ||||
| // serialisation and state-keeping. | ||||
| type Provider interface { | ||||
| 	Token(req []byte) (token []byte, err error) | ||||
| 	Verify(aReq *AuthenticatedRequest) bool | ||||
| } | ||||
|  | ||||
| // Standard implements an HMAC-SHA-256 authentication provider. It may | ||||
| // be supplied additional data at creation time that will be used as | ||||
| // request || additional-data with the HMAC. | ||||
| type Standard struct { | ||||
| 	key []byte | ||||
| 	ad  []byte | ||||
| } | ||||
|  | ||||
| // New generates a new standard authentication provider from the key | ||||
| // and additional data. The additional data will be used when | ||||
| // generating a new token. | ||||
| func New(key string, ad []byte) (*Standard, error) { | ||||
| 	if splitKey := strings.SplitN(key, ":", 2); len(splitKey) == 2 { | ||||
| 		switch splitKey[0] { | ||||
| 		case "env": | ||||
| 			key = os.Getenv(splitKey[1]) | ||||
| 		case "file": | ||||
| 			data, err := ioutil.ReadFile(splitKey[1]) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			key = string(data) | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("unknown key prefix: %s", splitKey[0]) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	keyBytes, err := hex.DecodeString(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &Standard{keyBytes, ad}, nil | ||||
| } | ||||
|  | ||||
| // Token generates a new authentication token from the request. | ||||
| func (p Standard) Token(req []byte) (token []byte, err error) { | ||||
| 	h := hmac.New(sha256.New, p.key) | ||||
| 	h.Write(req) | ||||
| 	h.Write(p.ad) | ||||
| 	return h.Sum(nil), nil | ||||
| } | ||||
|  | ||||
| // Verify determines whether an authenticated request is valid. | ||||
| func (p Standard) Verify(ad *AuthenticatedRequest) bool { | ||||
| 	if ad == nil { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// Standard token generation returns no error. | ||||
| 	token, _ := p.Token(ad.Request) | ||||
| 	if len(ad.Token) != len(token) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return hmac.Equal(token, ad.Token) | ||||
| } | ||||
							
								
								
									
										159
									
								
								vendor/github.com/cloudflare/cfssl/auth/auth_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								vendor/github.com/cloudflare/cfssl/auth/auth_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,159 @@ | ||||
| package auth | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"io/ioutil" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	testProvider   Provider | ||||
| 	testProviderAD Provider | ||||
| 	testKey        = "0123456789ABCDEF0123456789ABCDEF" | ||||
| 	testAD         = []byte{1, 2, 3, 4} // IP address 1.2.3.4 | ||||
| ) | ||||
|  | ||||
| func TestNew(t *testing.T) { | ||||
| 	_, err := New("ABC", nil) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("expected failure with improperly-hex-encoded key") | ||||
| 	} | ||||
|  | ||||
| 	testProvider, err = New(testKey, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	testProviderAD, err = New(testKey, testAD) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	testRequest1A = &AuthenticatedRequest{ | ||||
| 		Request: []byte(`testing 1 2 3`), | ||||
| 	} | ||||
| 	testRequest1B = &AuthenticatedRequest{ | ||||
| 		Request: []byte(`testing 1 2 3`), | ||||
| 	} | ||||
| 	testRequest2 = &AuthenticatedRequest{ | ||||
| 		Request: []byte(`testing 3 2 1`), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // Sanity check: can a newly-generated token be verified? | ||||
| func TestVerifyTrue(t *testing.T) { | ||||
| 	var err error | ||||
|  | ||||
| 	testRequest1A.Token, err = testProvider.Token(testRequest1A.Request) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	testRequest1B.Token, err = testProviderAD.Token(testRequest1B.Request) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if !testProvider.Verify(testRequest1A) { | ||||
| 		t.Fatal("failed to verify request 1A") | ||||
| 	} | ||||
|  | ||||
| 	if !testProviderAD.Verify(testRequest1B) { | ||||
| 		t.Fatal("failed to verify request 1B") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sanity check: ensure that additional data is actually used in | ||||
| // verification. | ||||
| func TestVerifyAD(t *testing.T) { | ||||
| 	if testProvider.Verify(testRequest1B) { | ||||
| 		t.Fatal("no-AD provider verifies request with AD") | ||||
| 	} | ||||
|  | ||||
| 	if testProviderAD.Verify(testRequest1A) { | ||||
| 		t.Fatal("AD provider verifies request without AD") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sanity check: verification fails if tokens are not the same length. | ||||
| func TestTokenLength(t *testing.T) { | ||||
| 	token := testRequest1A.Token[:] | ||||
| 	testRequest1A.Token = testRequest1A.Token[1:] | ||||
|  | ||||
| 	if testProvider.Verify(testRequest1A) { | ||||
| 		t.Fatal("invalid token should not be verified") | ||||
| 	} | ||||
|  | ||||
| 	testRequest1A.Token = token | ||||
| } | ||||
|  | ||||
| // Sanity check: token fails validation if the request is changed. | ||||
| func TestBadRequest(t *testing.T) { | ||||
| 	testRequest2.Token = testRequest1A.Token | ||||
| 	if testProvider.Verify(testRequest2) { | ||||
| 		t.Fatal("bad request should fail verification") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sanity check: a null request should fail to verify. | ||||
| func TestNullRequest(t *testing.T) { | ||||
| 	if testProvider.Verify(nil) { | ||||
| 		t.Fatal("null request should fail verification") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sanity check: verify a pre-generated authenticated request. | ||||
| func TestPreGenerated(t *testing.T) { | ||||
| 	in, err := ioutil.ReadFile("testdata/authrequest.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	var req AuthenticatedRequest | ||||
| 	err = json.Unmarshal(in, &req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if !testProvider.Verify(&req) { | ||||
| 		t.Fatal("failed to verify pre-generated request") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var bmRequest []byte | ||||
|  | ||||
| func TestLoadBenchmarkRequest(t *testing.T) { | ||||
| 	in, err := ioutil.ReadFile("testdata/request.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	bmRequest = in | ||||
| } | ||||
|  | ||||
| func BenchmarkToken(b *testing.B) { | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		_, err := testProvider.Token(bmRequest) | ||||
| 		if err != nil { | ||||
| 			b.Fatalf("%v", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func BenchmarkVerify(b *testing.B) { | ||||
| 	token, _ := testProvider.Token(bmRequest) | ||||
| 	req := &AuthenticatedRequest{ | ||||
| 		Token:   token, | ||||
| 		Request: bmRequest, | ||||
| 	} | ||||
| 	b.ResetTimer() | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		if !testProvider.Verify(req) { | ||||
| 			b.Fatal("failed to verify request") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/auth/testdata/authrequest.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/auth/testdata/authrequest.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| {"token": "tSU1WTE/322iXrOBfJSQ9/u1dleqpwUmCj1LXYHw07Y=", "request": "ewoJImhvc3RuYW1lIjogImt5bGVpc29tLm5ldCIsCgkicmVxdWVzdCI6ICItLS0tLUJFR0lOIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQoJICAgIE1JSUQwVENDQWpzQ0FRQXdZREVMTUFrR0ExVUVCaE1DVlZNeEVqQVFCZ05WQkFvVENXUnliM0J6YjI1a1pURVEKCSAgICBNQTRHQTFVRUN4TUhRMFl0UTJoaGRERVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVE1CRUdBMVVFCgkgICAgQ0JNS1EyRnNhV1p2Y201cFlUQ0NBYUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0dQQURDQ0FZb0NnZ0dCQU1jQwoJICAgIEdCbDVMVHJla0dGV2hvdGtkYlorUjFNbG9hcld4UXY5alA0QWVrdDhVT2ljeXBIdkZPNnhPdFN3SG8rcjMyaUUKCSAgICBxblM1eXYvMDFQMk1KdXlxbmRuY1RTTXNPbFQvN242N1RNMDB1MDFLLzljL3NvZ0tFS2pseXBsVFA3eUZkRy9jCgkgICAgT3UvOXFLYi9KYWxkMndFTEZZRTZ4cTJSREZ5eHlpWk9CM2c3WjdGeGE1ZDZhZGZHUndaek50VUw0LzhzK0x5aQoJICAgIHFkdzlJMWZrUWQ2MDRwb1pGTjB3clFzNGxmaFdUVWZnMHJIdWg1d2dHS1AzVnpacGJ0OEZiMXZOamZiSHRvaHgKCSAgICBHMlBDVTZKeStEYzFiU2ZVeldjUW5lbnA4NThXNEY4ejdwRjV5YmRuRlIzMTNIam9zcVhuRzI4eklUck9hZE1UCgkgICAgSGFKNnpPaGdFYWZVT1dYT3pqTm9mRkJGYTJJdUNBVCtJVFJZMXRDL2dxcHhHd0gveXVWTjE5Qkc4VXBuMCtIQQoJICAgIGllMm1LQ0hmU0JBS1QvWGU0dW1QZWF4U2JJcVdzVzhjaytkM2I0b3I5Ulp2NWNaUmNUM29pa0p0K1NRRzY5cFcKCSAgICA0T0FiYitBQnNzL05JdXJpNnowZTdERWVJTDV6bXlTSnFkdFlIZE5ZTjcrK3Y5eEJOc0w0SXNVNklFeTMrUUlECgkgICAgQVFBQm9DNHdMQVlKS29aSWh2Y05BUWtPTVI4d0hUQWJCZ05WSFJFRUZEQVNnaEJqWmk1a2NtOXdjMjl1WkdVdQoJICAgIGJtVjBNQXNHQ1NxR1NJYjNEUUVCREFPQ0FZRUFoTUFxQmlySStrMWFVM2xmQUdRaVNtOHl0T3paaWozODloSXIKCSAgICBuVXA4K1duVHVWVGI4WFozL1YrTDlFblRJbUY2dTF3ZWFqWGQzU3VlNDk1NzBMYlltSXV4QmtHcDUwL0JkVUR6CgkgICAgdUI2eHNoaEpXczEySnhVYjkxSW1tMGJUUncyek1xZXdnYTZmdHpaL0FLNG1zeFFBMlVJYmNXWmRzS2J1TTdzbwoJICAgIEpUZlZXOWlPd3FIdC82NFpqNHRCWmY5THpPRHI3a051S0tMbndqaXpIMTg3eGZJSWhkcmpGOFdTN0g5QVBCMU8KCSAgICBTdUVVRGZxaDBTV1IzbHRXdUF1VVdlbzZTS2NIVnVzeS9HNFlFK1BCeXcxZVY3RzRTYmVHNVowbytHT1VVSy9GCgkgICAgYjU1R21XMXhhNExBcnMxQSt6ZUZidkovQkFwc2JVMmI2V1ZtTmE3V3BIejdXWElGT0p1WUpnRWtWS1BKbkt1cwoJICAgIHFxczNGZ1VxejBadjdUSzhtTWlFVEpvWFpzNnpDdk15c1FldTNKL29qZ3RBanZNaHpRYzZQUy9udk90SmRJZysKCSAgICBIMHFYNDlmaHAxQnJZeXNsYWx6UUlGMCtIMHFTVWV5b1V5VjJ3YkxCQUxhcHhNZnZUVmxoTnduYWN0Y0tReHE0CgkgICAgK3dUKzJQVEowYk0vNUFWMFRPMVNQVDBBVmlKaAoJICAgIC0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLSIsCgkicHJvZmlsZSI6ICIiLAoJInJlbW90ZSI6ICIiLAoJImxhYmVsIjogInByaW1hcnkiCn0KCg=="} | ||||
							
								
								
									
										30
									
								
								vendor/github.com/cloudflare/cfssl/auth/testdata/request.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/cloudflare/cfssl/auth/testdata/request.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| { | ||||
| 	"hostname": "kyleisom.net", | ||||
| 	"request": "-----BEGIN CERTIFICATE REQUEST----- | ||||
| 	    MIID0TCCAjsCAQAwYDELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCWRyb3Bzb25kZTEQ | ||||
| 	    MA4GA1UECxMHQ0YtQ2hhdDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UE | ||||
| 	    CBMKQ2FsaWZvcm5pYTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMcC | ||||
| 	    GBl5LTrekGFWhotkdbZ+R1MloarWxQv9jP4Aekt8UOicypHvFO6xOtSwHo+r32iE | ||||
| 	    qnS5yv/01P2MJuyqndncTSMsOlT/7n67TM00u01K/9c/sogKEKjlyplTP7yFdG/c | ||||
| 	    Ou/9qKb/Jald2wELFYE6xq2RDFyxyiZOB3g7Z7Fxa5d6adfGRwZzNtUL4/8s+Lyi | ||||
| 	    qdw9I1fkQd604poZFN0wrQs4lfhWTUfg0rHuh5wgGKP3VzZpbt8Fb1vNjfbHtohx | ||||
| 	    G2PCU6Jy+Dc1bSfUzWcQnenp858W4F8z7pF5ybdnFR313HjosqXnG28zITrOadMT | ||||
| 	    HaJ6zOhgEafUOWXOzjNofFBFa2IuCAT+ITRY1tC/gqpxGwH/yuVN19BG8Upn0+HA | ||||
| 	    ie2mKCHfSBAKT/Xe4umPeaxSbIqWsW8ck+d3b4or9RZv5cZRcT3oikJt+SQG69pW | ||||
| 	    4OAbb+ABss/NIuri6z0e7DEeIL5zmySJqdtYHdNYN7++v9xBNsL4IsU6IEy3+QID | ||||
| 	    AQABoC4wLAYJKoZIhvcNAQkOMR8wHTAbBgNVHREEFDASghBjZi5kcm9wc29uZGUu | ||||
| 	    bmV0MAsGCSqGSIb3DQEBDAOCAYEAhMAqBirI+k1aU3lfAGQiSm8ytOzZij389hIr | ||||
| 	    nUp8+WnTuVTb8XZ3/V+L9EnTImF6u1weajXd3Sue49570LbYmIuxBkGp50/BdUDz | ||||
| 	    uB6xshhJWs12JxUb91Imm0bTRw2zMqewga6ftzZ/AK4msxQA2UIbcWZdsKbuM7so | ||||
| 	    JTfVW9iOwqHt/64Zj4tBZf9LzODr7kNuKKLnwjizH187xfIIhdrjF8WS7H9APB1O | ||||
| 	    SuEUDfqh0SWR3ltWuAuUWeo6SKcHVusy/G4YE+PByw1eV7G4SbeG5Z0o+GOUUK/F | ||||
| 	    b55GmW1xa4LArs1A+zeFbvJ/BApsbU2b6WVmNa7WpHz7WXIFOJuYJgEkVKPJnKus | ||||
| 	    qqs3FgUqz0Zv7TK8mMiETJoXZs6zCvMysQeu3J/ojgtAjvMhzQc6PS/nvOtJdIg+ | ||||
| 	    H0qX49fhp1BrYyslalzQIF0+H0qSUeyoUyV2wbLBALapxMfvTVlhNwnactcKQxq4 | ||||
| 	    +wT+2PTJ0bM/5AV0TO1SPT0AViJh | ||||
| 	    -----END CERTIFICATE REQUEST-----", | ||||
| 	"profile": "", | ||||
| 	"remote": "", | ||||
| 	"label": "primary" | ||||
| } | ||||
|  | ||||
							
								
								
									
										75
									
								
								vendor/github.com/cloudflare/cfssl/certdb/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/cloudflare/cfssl/certdb/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | ||||
| # certdb usage | ||||
|  | ||||
| Using a database enables additional functionality for existing commands when a | ||||
| db config is provided: | ||||
|  | ||||
|  - `sign` and `gencert` add a certificate to the certdb after signing it | ||||
|  - `serve` enables database functionality for the sign and revoke endpoints | ||||
|  | ||||
| A database is required for the following: | ||||
|  | ||||
|  - `revoke` marks certificates revoked in the database with an optional reason | ||||
|  - `ocsprefresh` refreshes the table of cached OCSP responses | ||||
|  - `ocspdump` outputs cached OCSP responses in a concatenated base64-encoded format | ||||
|  | ||||
| ## Setup/Migration | ||||
|  | ||||
| This directory stores [goose](https://bitbucket.org/liamstask/goose/) db migration scripts for various DB backends. | ||||
| Currently supported: | ||||
|  - MySQL in mysql | ||||
|  - PostgreSQL in pg | ||||
|  - SQLite in sqlite | ||||
|  | ||||
| ### Get goose | ||||
|  | ||||
|     go get bitbucket.org/liamstask/goose/cmd/goose | ||||
|  | ||||
| ### Use goose to start and terminate a MySQL DB | ||||
| To start a MySQL using goose: | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql up | ||||
|  | ||||
| To tear down a MySQL DB using goose | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql down | ||||
|  | ||||
| Note: the administration of MySQL DB is not included. We assume | ||||
| the databases being connected to are already created and access control | ||||
| is properly handled. | ||||
|  | ||||
| ### Use goose to start and terminate a PostgreSQL DB | ||||
| To start a PostgreSQL using goose: | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg up | ||||
|  | ||||
| To tear down a PostgreSQL DB using goose | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg down | ||||
|  | ||||
| Note: the administration of PostgreSQL DB is not included. We assume | ||||
| the databases being connected to are already created and access control | ||||
| is properly handled. | ||||
|  | ||||
| ### Use goose to start and terminate a SQLite DB | ||||
| To start a SQLite DB using goose: | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite up | ||||
|  | ||||
| To tear down a SQLite DB using goose | ||||
|  | ||||
|     goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite down | ||||
|  | ||||
| ## CFSSL Configuration | ||||
|  | ||||
| Several cfssl commands take a -db-config flag. Create a file with a | ||||
| JSON dictionary: | ||||
|  | ||||
|     {"driver":"sqlite3","data_source":"certs.db"} | ||||
|  | ||||
| or | ||||
|  | ||||
|     {"driver":"postgres","data_source":"postgres://user:password@host/db"} | ||||
|   | ||||
| or | ||||
|  | ||||
|     {"driver":"mysql","data_source":"user:password@tcp(hostname:3306)/db?parseTime=true"} | ||||
							
								
								
									
										42
									
								
								vendor/github.com/cloudflare/cfssl/certdb/certdb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/cloudflare/cfssl/certdb/certdb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| package certdb | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // CertificateRecord encodes a certificate and its metadata | ||||
| // that will be recorded in a database. | ||||
| type CertificateRecord struct { | ||||
| 	Serial    string    `db:"serial_number"` | ||||
| 	AKI       string    `db:"authority_key_identifier"` | ||||
| 	CALabel   string    `db:"ca_label"` | ||||
| 	Status    string    `db:"status"` | ||||
| 	Reason    int       `db:"reason"` | ||||
| 	Expiry    time.Time `db:"expiry"` | ||||
| 	RevokedAt time.Time `db:"revoked_at"` | ||||
| 	PEM       string    `db:"pem"` | ||||
| } | ||||
|  | ||||
| // OCSPRecord encodes a OCSP response body and its metadata | ||||
| // that will be recorded in a database. | ||||
| type OCSPRecord struct { | ||||
| 	Serial string    `db:"serial_number"` | ||||
| 	AKI    string    `db:"authority_key_identifier"` | ||||
| 	Body   string    `db:"body"` | ||||
| 	Expiry time.Time `db:"expiry"` | ||||
| } | ||||
|  | ||||
| // Accessor abstracts the CRUD of certdb objects from a DB. | ||||
| type Accessor interface { | ||||
| 	InsertCertificate(cr CertificateRecord) error | ||||
| 	GetCertificate(serial, aki string) ([]CertificateRecord, error) | ||||
| 	GetUnexpiredCertificates() ([]CertificateRecord, error) | ||||
| 	GetRevokedAndUnexpiredCertificates() ([]CertificateRecord, error) | ||||
| 	GetRevokedAndUnexpiredCertificatesByLabel(label string) ([]CertificateRecord, error) | ||||
| 	RevokeCertificate(serial, aki string, reasonCode int) error | ||||
| 	InsertOCSP(rr OCSPRecord) error | ||||
| 	GetOCSP(serial, aki string) ([]OCSPRecord, error) | ||||
| 	GetUnexpiredOCSPs() ([]OCSPRecord, error) | ||||
| 	UpdateOCSP(serial, aki, body string, expiry time.Time) error | ||||
| 	UpsertOCSP(serial, aki, body string, expiry time.Time) error | ||||
| } | ||||
							
								
								
									
										659
									
								
								vendor/github.com/cloudflare/cfssl/config/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										659
									
								
								vendor/github.com/cloudflare/cfssl/config/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,659 @@ | ||||
| // Package config contains the configuration logic for CFSSL. | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/auth" | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| 	"github.com/cloudflare/cfssl/log" | ||||
| 	ocspConfig "github.com/cloudflare/cfssl/ocsp/config" | ||||
| ) | ||||
|  | ||||
| // A CSRWhitelist stores booleans for fields in the CSR. If a CSRWhitelist is | ||||
| // not present in a SigningProfile, all of these fields may be copied from the | ||||
| // CSR into the signed certificate. If a CSRWhitelist *is* present in a | ||||
| // SigningProfile, only those fields with a `true` value in the CSRWhitelist may | ||||
| // be copied from the CSR to the signed certificate. Note that some of these | ||||
| // fields, like Subject, can be provided or partially provided through the API. | ||||
| // Since API clients are expected to be trusted, but CSRs are not, fields | ||||
| // provided through the API are not subject to whitelisting through this | ||||
| // mechanism. | ||||
| type CSRWhitelist struct { | ||||
| 	Subject, PublicKeyAlgorithm, PublicKey, SignatureAlgorithm bool | ||||
| 	DNSNames, IPAddresses, EmailAddresses                      bool | ||||
| } | ||||
|  | ||||
| // OID is our own version of asn1's ObjectIdentifier, so we can define a custom | ||||
| // JSON marshal / unmarshal. | ||||
| type OID asn1.ObjectIdentifier | ||||
|  | ||||
| // CertificatePolicy represents the ASN.1 PolicyInformation structure from | ||||
| // https://tools.ietf.org/html/rfc3280.html#page-106. | ||||
| // Valid values of Type are "id-qt-unotice" and "id-qt-cps" | ||||
| type CertificatePolicy struct { | ||||
| 	ID         OID | ||||
| 	Qualifiers []CertificatePolicyQualifier | ||||
| } | ||||
|  | ||||
| // CertificatePolicyQualifier represents a single qualifier from an ASN.1 | ||||
| // PolicyInformation structure. | ||||
| type CertificatePolicyQualifier struct { | ||||
| 	Type  string | ||||
| 	Value string | ||||
| } | ||||
|  | ||||
| // AuthRemote is an authenticated remote signer. | ||||
| type AuthRemote struct { | ||||
| 	RemoteName  string `json:"remote"` | ||||
| 	AuthKeyName string `json:"auth_key"` | ||||
| } | ||||
|  | ||||
| // CAConstraint specifies various CA constraints on the signed certificate. | ||||
| // CAConstraint would verify against (and override) the CA | ||||
| // extensions in the given CSR. | ||||
| type CAConstraint struct { | ||||
| 	IsCA           bool `json:"is_ca"` | ||||
| 	MaxPathLen     int  `json:"max_path_len"` | ||||
| 	MaxPathLenZero bool `json:"max_path_len_zero"` | ||||
| } | ||||
|  | ||||
| // A SigningProfile stores information that the CA needs to store | ||||
| // signature policy. | ||||
| type SigningProfile struct { | ||||
| 	Usage               []string     `json:"usages"` | ||||
| 	IssuerURL           []string     `json:"issuer_urls"` | ||||
| 	OCSP                string       `json:"ocsp_url"` | ||||
| 	CRL                 string       `json:"crl_url"` | ||||
| 	CAConstraint        CAConstraint `json:"ca_constraint"` | ||||
| 	OCSPNoCheck         bool         `json:"ocsp_no_check"` | ||||
| 	ExpiryString        string       `json:"expiry"` | ||||
| 	BackdateString      string       `json:"backdate"` | ||||
| 	AuthKeyName         string       `json:"auth_key"` | ||||
| 	RemoteName          string       `json:"remote"` | ||||
| 	NotBefore           time.Time    `json:"not_before"` | ||||
| 	NotAfter            time.Time    `json:"not_after"` | ||||
| 	NameWhitelistString string       `json:"name_whitelist"` | ||||
| 	AuthRemote          AuthRemote   `json:"auth_remote"` | ||||
| 	CTLogServers        []string     `json:"ct_log_servers"` | ||||
| 	AllowedExtensions   []OID        `json:"allowed_extensions"` | ||||
| 	CertStore           string       `json:"cert_store"` | ||||
|  | ||||
| 	Policies                    []CertificatePolicy | ||||
| 	Expiry                      time.Duration | ||||
| 	Backdate                    time.Duration | ||||
| 	Provider                    auth.Provider | ||||
| 	RemoteProvider              auth.Provider | ||||
| 	RemoteServer                string | ||||
| 	RemoteCAs                   *x509.CertPool | ||||
| 	ClientCert                  *tls.Certificate | ||||
| 	CSRWhitelist                *CSRWhitelist | ||||
| 	NameWhitelist               *regexp.Regexp | ||||
| 	ExtensionWhitelist          map[string]bool | ||||
| 	ClientProvidesSerialNumbers bool | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON unmarshals a JSON string into an OID. | ||||
| func (oid *OID) UnmarshalJSON(data []byte) (err error) { | ||||
| 	if data[0] != '"' || data[len(data)-1] != '"' { | ||||
| 		return errors.New("OID JSON string not wrapped in quotes." + string(data)) | ||||
| 	} | ||||
| 	data = data[1 : len(data)-1] | ||||
| 	parsedOid, err := parseObjectIdentifier(string(data)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*oid = OID(parsedOid) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MarshalJSON marshals an oid into a JSON string. | ||||
| func (oid OID) MarshalJSON() ([]byte, error) { | ||||
| 	return []byte(fmt.Sprintf(`"%v"`, asn1.ObjectIdentifier(oid))), nil | ||||
| } | ||||
|  | ||||
| func parseObjectIdentifier(oidString string) (oid asn1.ObjectIdentifier, err error) { | ||||
| 	validOID, err := regexp.MatchString("\\d(\\.\\d+)*", oidString) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if !validOID { | ||||
| 		err = errors.New("Invalid OID") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	segments := strings.Split(oidString, ".") | ||||
| 	oid = make(asn1.ObjectIdentifier, len(segments)) | ||||
| 	for i, intString := range segments { | ||||
| 		oid[i], err = strconv.Atoi(intString) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| const timeFormat = "2006-01-02T15:04:05" | ||||
|  | ||||
| // populate is used to fill in the fields that are not in JSON | ||||
| // | ||||
| // First, the ExpiryString parameter is needed to parse | ||||
| // expiration timestamps from JSON. The JSON decoder is not able to | ||||
| // decode a string time duration to a time.Duration, so this is called | ||||
| // when loading the configuration to properly parse and fill out the | ||||
| // Expiry parameter. | ||||
| // This function is also used to create references to the auth key | ||||
| // and default remote for the profile. | ||||
| // It returns true if ExpiryString is a valid representation of a | ||||
| // time.Duration, and the AuthKeyString and RemoteName point to | ||||
| // valid objects. It returns false otherwise. | ||||
| func (p *SigningProfile) populate(cfg *Config) error { | ||||
| 	if p == nil { | ||||
| 		return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("can't parse nil profile")) | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	if p.RemoteName == "" && p.AuthRemote.RemoteName == "" { | ||||
| 		log.Debugf("parse expiry in profile") | ||||
| 		if p.ExpiryString == "" { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("empty expiry string")) | ||||
| 		} | ||||
|  | ||||
| 		dur, err := time.ParseDuration(p.ExpiryString) | ||||
| 		if err != nil { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) | ||||
| 		} | ||||
|  | ||||
| 		log.Debugf("expiry is valid") | ||||
| 		p.Expiry = dur | ||||
|  | ||||
| 		if p.BackdateString != "" { | ||||
| 			dur, err = time.ParseDuration(p.BackdateString) | ||||
| 			if err != nil { | ||||
| 				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) | ||||
| 			} | ||||
|  | ||||
| 			p.Backdate = dur | ||||
| 		} | ||||
|  | ||||
| 		if !p.NotBefore.IsZero() && !p.NotAfter.IsZero() && p.NotAfter.Before(p.NotBefore) { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) | ||||
| 		} | ||||
|  | ||||
| 		if len(p.Policies) > 0 { | ||||
| 			for _, policy := range p.Policies { | ||||
| 				for _, qualifier := range policy.Qualifiers { | ||||
| 					if qualifier.Type != "" && qualifier.Type != "id-qt-unotice" && qualifier.Type != "id-qt-cps" { | ||||
| 						return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 							errors.New("invalid policy qualifier type")) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} else if p.RemoteName != "" { | ||||
| 		log.Debug("match remote in profile to remotes section") | ||||
| 		if p.AuthRemote.RemoteName != "" { | ||||
| 			log.Error("profile has both a remote and an auth remote specified") | ||||
| 			return cferr.New(cferr.PolicyError, cferr.InvalidPolicy) | ||||
| 		} | ||||
| 		if remote := cfg.Remotes[p.RemoteName]; remote != "" { | ||||
| 			if err := p.updateRemote(remote); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 				errors.New("failed to find remote in remotes section")) | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Debug("match auth remote in profile to remotes section") | ||||
| 		if remote := cfg.Remotes[p.AuthRemote.RemoteName]; remote != "" { | ||||
| 			if err := p.updateRemote(remote); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 				errors.New("failed to find remote in remotes section")) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if p.AuthKeyName != "" { | ||||
| 		log.Debug("match auth key in profile to auth_keys section") | ||||
| 		if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true { | ||||
| 			if key.Type == "standard" { | ||||
| 				p.Provider, err = auth.New(key.Key, nil) | ||||
| 				if err != nil { | ||||
| 					log.Debugf("failed to create new standard auth provider: %v", err) | ||||
| 					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 						errors.New("failed to create new standard auth provider")) | ||||
| 				} | ||||
| 			} else { | ||||
| 				log.Debugf("unknown authentication type %v", key.Type) | ||||
| 				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 					errors.New("unknown authentication type")) | ||||
| 			} | ||||
| 		} else { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 				errors.New("failed to find auth_key in auth_keys section")) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if p.AuthRemote.AuthKeyName != "" { | ||||
| 		log.Debug("match auth remote key in profile to auth_keys section") | ||||
| 		if key, ok := cfg.AuthKeys[p.AuthRemote.AuthKeyName]; ok == true { | ||||
| 			if key.Type == "standard" { | ||||
| 				p.RemoteProvider, err = auth.New(key.Key, nil) | ||||
| 				if err != nil { | ||||
| 					log.Debugf("failed to create new standard auth provider: %v", err) | ||||
| 					return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 						errors.New("failed to create new standard auth provider")) | ||||
| 				} | ||||
| 			} else { | ||||
| 				log.Debugf("unknown authentication type %v", key.Type) | ||||
| 				return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 					errors.New("unknown authentication type")) | ||||
| 			} | ||||
| 		} else { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 				errors.New("failed to find auth_remote's auth_key in auth_keys section")) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if p.NameWhitelistString != "" { | ||||
| 		log.Debug("compiling whitelist regular expression") | ||||
| 		rule, err := regexp.Compile(p.NameWhitelistString) | ||||
| 		if err != nil { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 				errors.New("failed to compile name whitelist section")) | ||||
| 		} | ||||
| 		p.NameWhitelist = rule | ||||
| 	} | ||||
|  | ||||
| 	p.ExtensionWhitelist = map[string]bool{} | ||||
| 	for _, oid := range p.AllowedExtensions { | ||||
| 		p.ExtensionWhitelist[asn1.ObjectIdentifier(oid).String()] = true | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // updateRemote takes a signing profile and initializes the remote server object | ||||
| // to the hostname:port combination sent by remote. | ||||
| func (p *SigningProfile) updateRemote(remote string) error { | ||||
| 	if remote != "" { | ||||
| 		p.RemoteServer = remote | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // OverrideRemotes takes a signing configuration and updates the remote server object | ||||
| // to the hostname:port combination sent by remote | ||||
| func (p *Signing) OverrideRemotes(remote string) error { | ||||
| 	if remote != "" { | ||||
| 		var err error | ||||
| 		for _, profile := range p.Profiles { | ||||
| 			err = profile.updateRemote(remote) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		err = p.Default.updateRemote(remote) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // SetClientCertKeyPairFromFile updates the properties to set client certificates for mutual | ||||
| // authenticated TLS remote requests | ||||
| func (p *Signing) SetClientCertKeyPairFromFile(certFile string, keyFile string) error { | ||||
| 	if certFile != "" && keyFile != "" { | ||||
| 		cert, err := helpers.LoadClientCertificate(certFile, keyFile) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		for _, profile := range p.Profiles { | ||||
| 			profile.ClientCert = cert | ||||
| 		} | ||||
| 		p.Default.ClientCert = cert | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // SetRemoteCAsFromFile reads root CAs from file and updates the properties to set remote CAs for TLS | ||||
| // remote requests | ||||
| func (p *Signing) SetRemoteCAsFromFile(caFile string) error { | ||||
| 	if caFile != "" { | ||||
| 		remoteCAs, err := helpers.LoadPEMCertPool(caFile) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		p.SetRemoteCAs(remoteCAs) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // SetRemoteCAs updates the properties to set remote CAs for TLS | ||||
| // remote requests | ||||
| func (p *Signing) SetRemoteCAs(remoteCAs *x509.CertPool) { | ||||
| 	for _, profile := range p.Profiles { | ||||
| 		profile.RemoteCAs = remoteCAs | ||||
| 	} | ||||
| 	p.Default.RemoteCAs = remoteCAs | ||||
| } | ||||
|  | ||||
| // NeedsRemoteSigner returns true if one of the profiles has a remote set | ||||
| func (p *Signing) NeedsRemoteSigner() bool { | ||||
| 	for _, profile := range p.Profiles { | ||||
| 		if profile.RemoteServer != "" { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if p.Default.RemoteServer != "" { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // NeedsLocalSigner returns true if one of the profiles doe not have a remote set | ||||
| func (p *Signing) NeedsLocalSigner() bool { | ||||
| 	for _, profile := range p.Profiles { | ||||
| 		if profile.RemoteServer == "" { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if p.Default.RemoteServer == "" { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Usages parses the list of key uses in the profile, translating them | ||||
| // to a list of X.509 key usages and extended key usages.  The unknown | ||||
| // uses are collected into a slice that is also returned. | ||||
| func (p *SigningProfile) Usages() (ku x509.KeyUsage, eku []x509.ExtKeyUsage, unk []string) { | ||||
| 	for _, keyUse := range p.Usage { | ||||
| 		if kuse, ok := KeyUsage[keyUse]; ok { | ||||
| 			ku |= kuse | ||||
| 		} else if ekuse, ok := ExtKeyUsage[keyUse]; ok { | ||||
| 			eku = append(eku, ekuse) | ||||
| 		} else { | ||||
| 			unk = append(unk, keyUse) | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // A valid profile must be a valid local profile or a valid remote profile. | ||||
| // A valid local profile has defined at least key usages to be used, and a | ||||
| // valid local default profile has defined at least a default expiration. | ||||
| // A valid remote profile (default or not) has remote signer initialized. | ||||
| // In addition, a remote profile must has a valid auth provider if auth | ||||
| // key defined. | ||||
| func (p *SigningProfile) validProfile(isDefault bool) bool { | ||||
| 	if p == nil { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	if p.AuthRemote.RemoteName == "" && p.AuthRemote.AuthKeyName != "" { | ||||
| 		log.Debugf("invalid auth remote profile: no remote signer specified") | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	if p.RemoteName != "" { | ||||
| 		log.Debugf("validate remote profile") | ||||
|  | ||||
| 		if p.RemoteServer == "" { | ||||
| 			log.Debugf("invalid remote profile: no remote signer specified") | ||||
| 			return false | ||||
| 		} | ||||
|  | ||||
| 		if p.AuthKeyName != "" && p.Provider == nil { | ||||
| 			log.Debugf("invalid remote profile: auth key name is defined but no auth provider is set") | ||||
| 			return false | ||||
| 		} | ||||
|  | ||||
| 		if p.AuthRemote.RemoteName != "" { | ||||
| 			log.Debugf("invalid remote profile: auth remote is also specified") | ||||
| 			return false | ||||
| 		} | ||||
| 	} else if p.AuthRemote.RemoteName != "" { | ||||
| 		log.Debugf("validate auth remote profile") | ||||
| 		if p.RemoteServer == "" { | ||||
| 			log.Debugf("invalid auth remote profile: no remote signer specified") | ||||
| 			return false | ||||
| 		} | ||||
|  | ||||
| 		if p.AuthRemote.AuthKeyName == "" || p.RemoteProvider == nil { | ||||
| 			log.Debugf("invalid auth remote profile: no auth key is defined") | ||||
| 			return false | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Debugf("validate local profile") | ||||
| 		if !isDefault { | ||||
| 			if len(p.Usage) == 0 { | ||||
| 				log.Debugf("invalid local profile: no usages specified") | ||||
| 				return false | ||||
| 			} else if _, _, unk := p.Usages(); len(unk) == len(p.Usage) { | ||||
| 				log.Debugf("invalid local profile: no valid usages") | ||||
| 				return false | ||||
| 			} | ||||
| 		} else { | ||||
| 			if p.Expiry == 0 { | ||||
| 				log.Debugf("invalid local profile: no expiry set") | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("profile is valid") | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // This checks if the SigningProfile object contains configurations that are only effective with a local signer | ||||
| // which has access to CA private key. | ||||
| func (p *SigningProfile) hasLocalConfig() bool { | ||||
| 	if p.Usage != nil || | ||||
| 		p.IssuerURL != nil || | ||||
| 		p.OCSP != "" || | ||||
| 		p.ExpiryString != "" || | ||||
| 		p.BackdateString != "" || | ||||
| 		p.CAConstraint.IsCA != false || | ||||
| 		!p.NotBefore.IsZero() || | ||||
| 		!p.NotAfter.IsZero() || | ||||
| 		p.NameWhitelistString != "" || | ||||
| 		len(p.CTLogServers) != 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // warnSkippedSettings prints a log warning message about skipped settings | ||||
| // in a SigningProfile, usually due to remote signer. | ||||
| func (p *Signing) warnSkippedSettings() { | ||||
| 	const warningMessage = `The configuration value by "usages", "issuer_urls", "ocsp_url", "crl_url", "ca_constraint", "expiry", "backdate", "not_before", "not_after", "cert_store" and "ct_log_servers" are skipped` | ||||
| 	if p == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if (p.Default.RemoteName != "" || p.Default.AuthRemote.RemoteName != "") && p.Default.hasLocalConfig() { | ||||
| 		log.Warning("default profile points to a remote signer: ", warningMessage) | ||||
| 	} | ||||
|  | ||||
| 	for name, profile := range p.Profiles { | ||||
| 		if (profile.RemoteName != "" || profile.AuthRemote.RemoteName != "") && profile.hasLocalConfig() { | ||||
| 			log.Warningf("Profiles[%s] points to a remote signer: %s", name, warningMessage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Signing codifies the signature configuration policy for a CA. | ||||
| type Signing struct { | ||||
| 	Profiles map[string]*SigningProfile `json:"profiles"` | ||||
| 	Default  *SigningProfile            `json:"default"` | ||||
| } | ||||
|  | ||||
| // Config stores configuration information for the CA. | ||||
| type Config struct { | ||||
| 	Signing  *Signing           `json:"signing"` | ||||
| 	OCSP     *ocspConfig.Config `json:"ocsp"` | ||||
| 	AuthKeys map[string]AuthKey `json:"auth_keys,omitempty"` | ||||
| 	Remotes  map[string]string  `json:"remotes,omitempty"` | ||||
| } | ||||
|  | ||||
| // Valid ensures that Config is a valid configuration. It should be | ||||
| // called immediately after parsing a configuration file. | ||||
| func (c *Config) Valid() bool { | ||||
| 	return c.Signing.Valid() | ||||
| } | ||||
|  | ||||
| // Valid checks the signature policies, ensuring they are valid | ||||
| // policies. A policy is valid if it has defined at least key usages | ||||
| // to be used, and a valid default profile has defined at least a | ||||
| // default expiration. | ||||
| func (p *Signing) Valid() bool { | ||||
| 	if p == nil { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("validating configuration") | ||||
| 	if !p.Default.validProfile(true) { | ||||
| 		log.Debugf("default profile is invalid") | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	for _, sp := range p.Profiles { | ||||
| 		if !sp.validProfile(false) { | ||||
| 			log.Debugf("invalid profile") | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	p.warnSkippedSettings() | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // KeyUsage contains a mapping of string names to key usages. | ||||
| var KeyUsage = map[string]x509.KeyUsage{ | ||||
| 	"signing":            x509.KeyUsageDigitalSignature, | ||||
| 	"digital signature":  x509.KeyUsageDigitalSignature, | ||||
| 	"content commitment": x509.KeyUsageContentCommitment, | ||||
| 	"key encipherment":   x509.KeyUsageKeyEncipherment, | ||||
| 	"key agreement":      x509.KeyUsageKeyAgreement, | ||||
| 	"data encipherment":  x509.KeyUsageDataEncipherment, | ||||
| 	"cert sign":          x509.KeyUsageCertSign, | ||||
| 	"crl sign":           x509.KeyUsageCRLSign, | ||||
| 	"encipher only":      x509.KeyUsageEncipherOnly, | ||||
| 	"decipher only":      x509.KeyUsageDecipherOnly, | ||||
| } | ||||
|  | ||||
| // ExtKeyUsage contains a mapping of string names to extended key | ||||
| // usages. | ||||
| var ExtKeyUsage = map[string]x509.ExtKeyUsage{ | ||||
| 	"any":              x509.ExtKeyUsageAny, | ||||
| 	"server auth":      x509.ExtKeyUsageServerAuth, | ||||
| 	"client auth":      x509.ExtKeyUsageClientAuth, | ||||
| 	"code signing":     x509.ExtKeyUsageCodeSigning, | ||||
| 	"email protection": x509.ExtKeyUsageEmailProtection, | ||||
| 	"s/mime":           x509.ExtKeyUsageEmailProtection, | ||||
| 	"ipsec end system": x509.ExtKeyUsageIPSECEndSystem, | ||||
| 	"ipsec tunnel":     x509.ExtKeyUsageIPSECTunnel, | ||||
| 	"ipsec user":       x509.ExtKeyUsageIPSECUser, | ||||
| 	"timestamping":     x509.ExtKeyUsageTimeStamping, | ||||
| 	"ocsp signing":     x509.ExtKeyUsageOCSPSigning, | ||||
| 	"microsoft sgc":    x509.ExtKeyUsageMicrosoftServerGatedCrypto, | ||||
| 	"netscape sgc":     x509.ExtKeyUsageNetscapeServerGatedCrypto, | ||||
| } | ||||
|  | ||||
| // An AuthKey contains an entry for a key used for authentication. | ||||
| type AuthKey struct { | ||||
| 	// Type contains information needed to select the appropriate | ||||
| 	// constructor. For example, "standard" for HMAC-SHA-256, | ||||
| 	// "standard-ip" for HMAC-SHA-256 incorporating the client's | ||||
| 	// IP. | ||||
| 	Type string `json:"type"` | ||||
| 	// Key contains the key information, such as a hex-encoded | ||||
| 	// HMAC key. | ||||
| 	Key string `json:"key"` | ||||
| } | ||||
|  | ||||
| // DefaultConfig returns a default configuration specifying basic key | ||||
| // usage and a 1 year expiration time. The key usages chosen are | ||||
| // signing, key encipherment, client auth and server auth. | ||||
| func DefaultConfig() *SigningProfile { | ||||
| 	d := helpers.OneYear | ||||
| 	return &SigningProfile{ | ||||
| 		Usage:        []string{"signing", "key encipherment", "server auth", "client auth"}, | ||||
| 		Expiry:       d, | ||||
| 		ExpiryString: "8760h", | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // LoadFile attempts to load the configuration file stored at the path | ||||
| // and returns the configuration. On error, it returns nil. | ||||
| func LoadFile(path string) (*Config, error) { | ||||
| 	log.Debugf("loading configuration file from %s", path) | ||||
| 	if path == "" { | ||||
| 		return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("invalid path")) | ||||
| 	} | ||||
|  | ||||
| 	body, err := ioutil.ReadFile(path) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("could not read configuration file")) | ||||
| 	} | ||||
|  | ||||
| 	return LoadConfig(body) | ||||
| } | ||||
|  | ||||
| // LoadConfig attempts to load the configuration from a byte slice. | ||||
| // On error, it returns nil. | ||||
| func LoadConfig(config []byte) (*Config, error) { | ||||
| 	var cfg = &Config{} | ||||
| 	err := json.Unmarshal(config, &cfg) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, | ||||
| 			errors.New("failed to unmarshal configuration: "+err.Error())) | ||||
| 	} | ||||
|  | ||||
| 	if cfg.Signing == nil { | ||||
| 		return nil, errors.New("No \"signing\" field present") | ||||
| 	} | ||||
|  | ||||
| 	if cfg.Signing.Default == nil { | ||||
| 		log.Debugf("no default given: using default config") | ||||
| 		cfg.Signing.Default = DefaultConfig() | ||||
| 	} else { | ||||
| 		if err := cfg.Signing.Default.populate(cfg); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for k := range cfg.Signing.Profiles { | ||||
| 		if err := cfg.Signing.Profiles[k].populate(cfg); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !cfg.Valid() { | ||||
| 		return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("invalid configuration")) | ||||
| 	} | ||||
|  | ||||
| 	log.Debugf("configuration ok") | ||||
| 	return cfg, nil | ||||
| } | ||||
							
								
								
									
										537
									
								
								vendor/github.com/cloudflare/cfssl/config/config_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										537
									
								
								vendor/github.com/cloudflare/cfssl/config/config_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,537 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var expiry = 1 * time.Minute | ||||
|  | ||||
| var invalidProfileConfig = &Config{ | ||||
| 	Signing: &Signing{ | ||||
| 		Profiles: map[string]*SigningProfile{ | ||||
| 			"invalid": { | ||||
| 				Usage:  []string{"wiretapping"}, | ||||
| 				Expiry: expiry, | ||||
| 			}, | ||||
| 			"empty": {}, | ||||
| 		}, | ||||
| 		Default: &SigningProfile{ | ||||
| 			Usage:  []string{"digital signature"}, | ||||
| 			Expiry: expiry, | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| var invalidDefaultConfig = &Config{ | ||||
| 	Signing: &Signing{ | ||||
| 		Profiles: map[string]*SigningProfile{ | ||||
| 			"key usage": { | ||||
| 				Usage: []string{"digital signature"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		Default: &SigningProfile{ | ||||
| 			Usage: []string{"s/mime"}, | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| var validConfig = &Config{ | ||||
| 	Signing: &Signing{ | ||||
| 		Profiles: map[string]*SigningProfile{ | ||||
| 			"valid": { | ||||
| 				Usage:  []string{"digital signature"}, | ||||
| 				Expiry: expiry, | ||||
| 			}, | ||||
| 		}, | ||||
| 		Default: &SigningProfile{ | ||||
| 			Usage:  []string{"digital signature"}, | ||||
| 			Expiry: expiry, | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| var validMixedConfig = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"auth_key": "sample", | ||||
| 				"remote": "localhost" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var validMinimalRemoteConfig = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_key": "sample", | ||||
| 			"remote": "localhost" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var validMinimalRemoteConfig2 = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_remote":{ | ||||
| 			    "auth_key": "sample", | ||||
| 			    "remote": "localhost" | ||||
| 		    } | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var invalidConflictRemoteConfig = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_remote":{ | ||||
| 			    "auth_key": "sample", | ||||
| 			    "remote": "localhost" | ||||
| 		    }, | ||||
| 			"remote": "localhost" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var invalidRemoteConfig = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_remotes_typos":{ | ||||
| 			    "auth_key": "sample", | ||||
| 			    "remote": "localhost" | ||||
| 		    } | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var invalidAuthRemoteConfigMissingRemote = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_remote":{ | ||||
| 			    "auth_key": "sample" | ||||
| 		    } | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var invalidAuthRemoteConfigMissingKey = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"auth_remote":{ | ||||
| 			    "remote": "localhost" | ||||
| 		    } | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"sample": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var validMinimalLocalConfig = ` | ||||
| { | ||||
| 	"signing": { | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	} | ||||
| }` | ||||
|  | ||||
| var validLocalConfigsWithCAConstraint = []string{ | ||||
| 	`{ | ||||
| 		"signing": { | ||||
| 			"default": { | ||||
| 				"usages": ["digital signature", "email protection"], | ||||
| 				"ca_constraint": { "is_ca": true }, | ||||
| 				"expiry": "8000h" | ||||
| 			} | ||||
| 		} | ||||
| 	}`, | ||||
| 	`{ | ||||
| 		"signing": { | ||||
| 			"default": { | ||||
| 				"usages": ["digital signature", "email protection"], | ||||
| 				"ca_constraint": { "is_ca": true, "max_path_len": 1 }, | ||||
| 				"expiry": "8000h" | ||||
| 			} | ||||
| 		} | ||||
| 	}`, | ||||
| 	`{ | ||||
| 		"signing": { | ||||
| 			"default": { | ||||
| 				"usages": ["digital signature", "email protection"], | ||||
| 				"ca_constraint": { "is_ca": true, "max_path_len_zero": true }, | ||||
| 				"expiry": "8000h" | ||||
| 			} | ||||
| 		} | ||||
| 	}`, | ||||
| } | ||||
|  | ||||
| func TestInvalidProfile(t *testing.T) { | ||||
| 	if invalidProfileConfig.Signing.Profiles["invalid"].validProfile(false) { | ||||
| 		t.Fatal("invalid profile accepted as valid") | ||||
| 	} | ||||
|  | ||||
| 	if invalidProfileConfig.Signing.Profiles["empty"].validProfile(false) { | ||||
| 		t.Fatal("invalid profile accepted as valid") | ||||
| 	} | ||||
|  | ||||
| 	if invalidProfileConfig.Valid() { | ||||
| 		t.Fatal("invalid config accepted as valid") | ||||
| 	} | ||||
|  | ||||
| 	if !invalidProfileConfig.Signing.Profiles["invalid"].validProfile(true) { | ||||
| 		t.Fatal("invalid profile should be a valid default profile") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRemoteProfiles(t *testing.T) { | ||||
| 	var validRemoteProfile = &SigningProfile{ | ||||
| 		RemoteName:   "localhost", | ||||
| 		RemoteServer: "localhost:8080", | ||||
| 	} | ||||
|  | ||||
| 	var invalidRemoteProfile = &SigningProfile{ | ||||
| 		RemoteName: "localhost", | ||||
| 	} | ||||
|  | ||||
| 	var invalidRemoteAuthProfile = &SigningProfile{ | ||||
| 		RemoteName:   "localhost", | ||||
| 		RemoteServer: "localhost:8080", | ||||
| 		AuthKeyName:  "blahblah", | ||||
| 	} | ||||
|  | ||||
| 	if !validRemoteProfile.validProfile(true) || | ||||
| 		!validRemoteProfile.validProfile(false) { | ||||
| 		t.Fatal("valid remote profile is rejected.") | ||||
| 	} | ||||
|  | ||||
| 	if invalidRemoteProfile.validProfile(true) || | ||||
| 		invalidRemoteProfile.validProfile(false) { | ||||
| 		t.Fatal("invalid remote profile is accepted.") | ||||
| 	} | ||||
|  | ||||
| 	if invalidRemoteAuthProfile.validProfile(true) || | ||||
| 		invalidRemoteAuthProfile.validProfile(false) { | ||||
| 		t.Fatal("invalid remote profile is accepted.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestInvalidDefault(t *testing.T) { | ||||
| 	if invalidDefaultConfig.Signing.Default.validProfile(true) { | ||||
| 		t.Fatal("invalid default accepted as valid") | ||||
| 	} | ||||
|  | ||||
| 	if invalidDefaultConfig.Valid() { | ||||
| 		t.Fatal("invalid config accepted as valid") | ||||
| 	} | ||||
|  | ||||
| 	if !invalidDefaultConfig.Signing.Default.validProfile(false) { | ||||
| 		t.Fatal("invalid default profile should be a valid profile") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestValidConfig(t *testing.T) { | ||||
| 	if !validConfig.Valid() { | ||||
| 		t.Fatal("Valid config is not valid") | ||||
| 	} | ||||
| 	bytes, _ := json.Marshal(validConfig) | ||||
| 	fmt.Printf("%v", string(bytes)) | ||||
| } | ||||
|  | ||||
| func TestDefaultConfig(t *testing.T) { | ||||
| 	if !DefaultConfig().validProfile(false) { | ||||
| 		t.Fatal("global default signing profile should be a valid profile.") | ||||
| 	} | ||||
|  | ||||
| 	if !DefaultConfig().validProfile(true) { | ||||
| 		t.Fatal("global default signing profile should be a valid default profile") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestParse(t *testing.T) { | ||||
| 	var validProfiles = []*SigningProfile{ | ||||
| 		{ | ||||
| 			ExpiryString: "8760h", | ||||
| 		}, | ||||
| 		{ | ||||
| 			ExpiryString: "168h", | ||||
| 		}, | ||||
| 		{ | ||||
| 			ExpiryString: "300s", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	var invalidProfiles = []*SigningProfile{ | ||||
| 		nil, | ||||
| 		{}, | ||||
| 		{ | ||||
| 			ExpiryString: "", | ||||
| 		}, | ||||
| 		{ | ||||
| 			ExpiryString: "365d", | ||||
| 		}, | ||||
| 		{ | ||||
| 			ExpiryString: "1y", | ||||
| 		}, | ||||
| 		{ | ||||
| 			ExpiryString: "one year", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, p := range validProfiles { | ||||
| 		if p.populate(nil) != nil { | ||||
| 			t.Fatalf("Failed to parse ExpiryString=%s", p.ExpiryString) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for _, p := range invalidProfiles { | ||||
| 		if p.populate(nil) == nil { | ||||
| 			if p != nil { | ||||
| 				t.Fatalf("ExpiryString=%s should not be parseable", p.ExpiryString) | ||||
| 			} | ||||
| 			t.Fatalf("Nil profile should not be parseable") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestLoadFile(t *testing.T) { | ||||
| 	validConfigFiles := []string{ | ||||
| 		"testdata/valid_config.json", | ||||
| 		"testdata/valid_config_auth.json", | ||||
| 		"testdata/valid_config_no_default.json", | ||||
| 		"testdata/valid_config_auth_no_default.json", | ||||
| 	} | ||||
|  | ||||
| 	for _, configFile := range validConfigFiles { | ||||
| 		_, err := LoadFile(configFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Load valid config file failed.", configFile, "error is ", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLoadInvalidConfigFile(t *testing.T) { | ||||
| 	invalidConfigFiles := []string{"", "testdata/no_such_file", | ||||
| 		"testdata/invalid_default.json", | ||||
| 		"testdata/invalid_profiles.json", | ||||
| 		"testdata/invalid_usage.json", | ||||
| 		"testdata/invalid_config.json", | ||||
| 		"testdata/invalid_auth.json", | ||||
| 		"testdata/invalid_auth_bad_key.json", | ||||
| 		"testdata/invalid_no_auth_keys.json", | ||||
| 		"testdata/invalid_remote.json", | ||||
| 		"testdata/invalid_no_remotes.json", | ||||
| 	} | ||||
| 	for _, configFile := range invalidConfigFiles { | ||||
| 		_, err := LoadFile(configFile) | ||||
| 		if err == nil { | ||||
| 			t.Fatal("Invalid config is loaded.", configFile) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestNeedLocalSigner(t *testing.T) { | ||||
|  | ||||
| 	c, err := LoadConfig([]byte(validMixedConfig)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("load valid config failed:", err) | ||||
| 	} | ||||
|  | ||||
| 	// This signing config needs both local signer and remote signer. | ||||
| 	if c.Signing.NeedsLocalSigner() != true { | ||||
| 		t.Fatal("incorrect NeedsLocalSigner().") | ||||
| 	} | ||||
|  | ||||
| 	if c.Signing.NeedsRemoteSigner() != true { | ||||
| 		t.Fatal("incorrect NeedsRemoteSigner()") | ||||
| 	} | ||||
|  | ||||
| 	remoteConfig, err := LoadConfig([]byte(validMinimalRemoteConfig)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Load valid config failed:", err) | ||||
| 	} | ||||
|  | ||||
| 	if remoteConfig.Signing.NeedsLocalSigner() != false { | ||||
| 		t.Fatal("incorrect NeedsLocalSigner().") | ||||
| 	} | ||||
|  | ||||
| 	if remoteConfig.Signing.NeedsRemoteSigner() != true { | ||||
| 		t.Fatal("incorrect NeedsRemoteSigner().") | ||||
| 	} | ||||
|  | ||||
| 	localConfig, err := LoadConfig([]byte(validMinimalLocalConfig)) | ||||
| 	if localConfig.Signing.NeedsLocalSigner() != true { | ||||
| 		t.Fatal("incorrect NeedsLocalSigner().") | ||||
| 	} | ||||
|  | ||||
| 	if localConfig.Signing.NeedsRemoteSigner() != false { | ||||
| 		t.Fatal("incorrect NeedsRemoteSigner().") | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestOverrideRemotes(t *testing.T) { | ||||
| 	c, err := LoadConfig([]byte(validMixedConfig)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("load valid config failed:", err) | ||||
| 	} | ||||
|  | ||||
| 	host := "localhost:8888" | ||||
| 	c.Signing.OverrideRemotes(host) | ||||
|  | ||||
| 	if c.Signing.Default.RemoteServer != host { | ||||
| 		t.Fatal("should override default profile's RemoteServer") | ||||
| 	} | ||||
|  | ||||
| 	for _, p := range c.Signing.Profiles { | ||||
| 		if p.RemoteServer != host { | ||||
| 			t.Fatal("failed to override profile's RemoteServer") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestAuthRemoteConfig(t *testing.T) { | ||||
| 	c, err := LoadConfig([]byte(validMinimalRemoteConfig2)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("load valid config failed:", err) | ||||
| 	} | ||||
|  | ||||
| 	if c.Signing.Default.RemoteServer != "127.0.0.1:8888" { | ||||
| 		t.Fatal("load valid config failed: incorrect remote server") | ||||
| 	} | ||||
|  | ||||
| 	host := "localhost:8888" | ||||
| 	c.Signing.OverrideRemotes(host) | ||||
|  | ||||
| 	if c.Signing.Default.RemoteServer != host { | ||||
| 		t.Fatal("should override default profile's RemoteServer") | ||||
| 	} | ||||
|  | ||||
| 	for _, p := range c.Signing.Profiles { | ||||
| 		if p.RemoteServer != host { | ||||
| 			t.Fatal("failed to override profile's RemoteServer") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDuplicateRemoteConfig(t *testing.T) { | ||||
| 	_, err := LoadConfig([]byte(invalidConflictRemoteConfig)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("fail to reject invalid config") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestBadAuthRemoteConfig(t *testing.T) { | ||||
| 	_, err := LoadConfig([]byte(invalidRemoteConfig)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("load invalid config should failed") | ||||
| 	} | ||||
|  | ||||
| 	_, err = LoadConfig([]byte(invalidAuthRemoteConfigMissingRemote)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("load invalid config should failed") | ||||
| 	} | ||||
|  | ||||
| 	_, err = LoadConfig([]byte(invalidAuthRemoteConfigMissingKey)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("load invalid config should failed") | ||||
| 	} | ||||
|  | ||||
| 	var p *Signing | ||||
| 	if p.Valid() { | ||||
| 		t.Fatal("nil Signing config should be invalid") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestValidCAConstraint(t *testing.T) { | ||||
| 	for _, config := range validLocalConfigsWithCAConstraint { | ||||
| 		_, err := LoadConfig([]byte(config)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("can't parse valid ca constraint") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_auth.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_auth.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"remote": "localhost", | ||||
| 				"auth_key": "garbage" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"stadardo", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_auth_bad_key.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_auth_bad_key.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"remote": "localhost", | ||||
| 				"auth_key": "garbage" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"BAD_KEY" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										17
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "invalid_expiry" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_no_auth_keys.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_no_auth_keys.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"remote": "localhost", | ||||
| 				"auth_key": "garbage" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_no_remotes.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_no_remotes.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"auth_key": "garbage", | ||||
| 				"remote": "localhoster" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_profile.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_profile.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "invalid_expiry" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_remotes.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_remotes.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"auth_key": "garbage", | ||||
| 				"remote": "localhoster" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_usage.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/invalid_usage.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["BAD_USAGE"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_key": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										29
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_auth.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_auth.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h", | ||||
| 				"auth_key": "garbage", | ||||
| 				"remote": "localhost" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		}, | ||||
| 		"default": { | ||||
| 			"usages": ["digital signature", "email protection"], | ||||
| 			"expiry": "8000h" | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_auth_no_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_auth_no_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"auth_key": "garbage", | ||||
| 				"remote": "localhost" | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"auth_keys": { | ||||
| 		"garbage": { | ||||
| 			"type":"standard", | ||||
| 			"key":"0123456789ABCDEF0123456789ABCDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	"remotes": { | ||||
| 		"localhost": "127.0.0.1:8888" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										14
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_no_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/cloudflare/cfssl/config/testdata/valid_config_no_default.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| { | ||||
| 	"signing": { | ||||
| 		"profiles": { | ||||
| 			"CA": { | ||||
| 				"usages": ["cert sign"], | ||||
| 				"expiry": "720h" | ||||
| 			}, | ||||
| 			"email": { | ||||
| 				"usages": ["s/mime"], | ||||
| 				"expiry": "720h" | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										188
									
								
								vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,188 @@ | ||||
| // Package pkcs7 implements the subset of the CMS PKCS #7 datatype that is typically | ||||
| // used to package certificates and CRLs.  Using openssl, every certificate converted | ||||
| // to PKCS #7 format from another encoding such as PEM conforms to this implementation. | ||||
| // reference: https://www.openssl.org/docs/man1.1.0/apps/crl2pkcs7.html | ||||
| // | ||||
| //			PKCS #7 Data type, reference: https://tools.ietf.org/html/rfc2315 | ||||
| // | ||||
| // The full pkcs#7 cryptographic message syntax allows for cryptographic enhancements, | ||||
| // for example data can be encrypted and signed and then packaged through pkcs#7 to be | ||||
| // sent over a network and then verified and decrypted.  It is asn1, and the type of | ||||
| // PKCS #7 ContentInfo, which comprises the PKCS #7 structure, is: | ||||
| // | ||||
| //			ContentInfo ::= SEQUENCE { | ||||
| //				contentType ContentType, | ||||
| //				content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL | ||||
| //			} | ||||
| // | ||||
| // There are 6 possible ContentTypes, data, signedData, envelopedData, | ||||
| // signedAndEnvelopedData, digestedData, and encryptedData.  Here signedData, Data, and encrypted | ||||
| // Data are implemented, as the degenerate case of signedData without a signature is the typical | ||||
| // format for transferring certificates and CRLS, and Data and encryptedData are used in PKCS #12 | ||||
| // formats. | ||||
| // The ContentType signedData has the form: | ||||
| // | ||||
| // | ||||
| //			signedData ::= SEQUENCE { | ||||
| //				version Version, | ||||
| //				digestAlgorithms DigestAlgorithmIdentifiers, | ||||
| //				contentInfo ContentInfo, | ||||
| //				certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL | ||||
| //				crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, | ||||
| //				signerInfos SignerInfos | ||||
| //			} | ||||
| // | ||||
| // As of yet signerInfos and digestAlgorithms are not parsed, as they are not relevant to | ||||
| // this system's use of PKCS #7 data.  Version is an integer type, note that PKCS #7 is | ||||
| // recursive, this second layer of ContentInfo is similar ignored for our degenerate | ||||
| // usage.  The ExtendedCertificatesAndCertificates type consists of a sequence of choices | ||||
| // between PKCS #6 extended certificates and x509 certificates.  Any sequence consisting | ||||
| // of any number of extended certificates is not yet supported in this implementation. | ||||
| // | ||||
| // The ContentType Data is simply a raw octet string and is parsed directly into a Go []byte slice. | ||||
| // | ||||
| // The ContentType encryptedData is the most complicated and its form can be gathered by | ||||
| // the go type below.  It essentially contains a raw octet string of encrypted data and an | ||||
| // algorithm identifier for use in decrypting this data. | ||||
| package pkcs7 | ||||
|  | ||||
| import ( | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"errors" | ||||
|  | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| ) | ||||
|  | ||||
| // Types used for asn1 Unmarshaling. | ||||
|  | ||||
| type signedData struct { | ||||
| 	Version          int | ||||
| 	DigestAlgorithms asn1.RawValue | ||||
| 	ContentInfo      asn1.RawValue | ||||
| 	Certificates     asn1.RawValue `asn1:"optional" asn1:"tag:0"` | ||||
| 	Crls             asn1.RawValue `asn1:"optional"` | ||||
| 	SignerInfos      asn1.RawValue | ||||
| } | ||||
|  | ||||
| type initPKCS7 struct { | ||||
| 	Raw         asn1.RawContent | ||||
| 	ContentType asn1.ObjectIdentifier | ||||
| 	Content     asn1.RawValue `asn1:"tag:0,explicit,optional"` | ||||
| } | ||||
|  | ||||
| // Object identifier strings of the three implemented PKCS7 types. | ||||
| const ( | ||||
| 	ObjIDData          = "1.2.840.113549.1.7.1" | ||||
| 	ObjIDSignedData    = "1.2.840.113549.1.7.2" | ||||
| 	ObjIDEncryptedData = "1.2.840.113549.1.7.6" | ||||
| ) | ||||
|  | ||||
| // PKCS7 represents the ASN1 PKCS #7 Content type.  It contains one of three | ||||
| // possible types of Content objects, as denoted by the object identifier in | ||||
| // the ContentInfo field, the other two being nil.  SignedData | ||||
| // is the degenerate SignedData Content info without signature used | ||||
| // to hold certificates and crls.  Data is raw bytes, and EncryptedData | ||||
| // is as defined in PKCS #7 standard. | ||||
| type PKCS7 struct { | ||||
| 	Raw         asn1.RawContent | ||||
| 	ContentInfo string | ||||
| 	Content     Content | ||||
| } | ||||
|  | ||||
| // Content implements three of the six possible PKCS7 data types.  Only one is non-nil. | ||||
| type Content struct { | ||||
| 	Data          []byte | ||||
| 	SignedData    SignedData | ||||
| 	EncryptedData EncryptedData | ||||
| } | ||||
|  | ||||
| // SignedData defines the typical carrier of certificates and crls. | ||||
| type SignedData struct { | ||||
| 	Raw          asn1.RawContent | ||||
| 	Version      int | ||||
| 	Certificates []*x509.Certificate | ||||
| 	Crl          *pkix.CertificateList | ||||
| } | ||||
|  | ||||
| // Data contains raw bytes.  Used as a subtype in PKCS12. | ||||
| type Data struct { | ||||
| 	Bytes []byte | ||||
| } | ||||
|  | ||||
| // EncryptedData contains encrypted data.  Used as a subtype in PKCS12. | ||||
| type EncryptedData struct { | ||||
| 	Raw                  asn1.RawContent | ||||
| 	Version              int | ||||
| 	EncryptedContentInfo EncryptedContentInfo | ||||
| } | ||||
|  | ||||
| // EncryptedContentInfo is a subtype of PKCS7EncryptedData. | ||||
| type EncryptedContentInfo struct { | ||||
| 	Raw                        asn1.RawContent | ||||
| 	ContentType                asn1.ObjectIdentifier | ||||
| 	ContentEncryptionAlgorithm pkix.AlgorithmIdentifier | ||||
| 	EncryptedContent           []byte `asn1:"tag:0,optional"` | ||||
| } | ||||
|  | ||||
| // ParsePKCS7 attempts to parse the DER encoded bytes of a | ||||
| // PKCS7 structure. | ||||
| func ParsePKCS7(raw []byte) (msg *PKCS7, err error) { | ||||
|  | ||||
| 	var pkcs7 initPKCS7 | ||||
| 	_, err = asn1.Unmarshal(raw, &pkcs7) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 	} | ||||
|  | ||||
| 	msg = new(PKCS7) | ||||
| 	msg.Raw = pkcs7.Raw | ||||
| 	msg.ContentInfo = pkcs7.ContentType.String() | ||||
| 	switch { | ||||
| 	case msg.ContentInfo == ObjIDData: | ||||
| 		msg.ContentInfo = "Data" | ||||
| 		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &msg.Content.Data) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 		} | ||||
| 	case msg.ContentInfo == ObjIDSignedData: | ||||
| 		msg.ContentInfo = "SignedData" | ||||
| 		var signedData signedData | ||||
| 		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &signedData) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 		} | ||||
| 		if len(signedData.Certificates.Bytes) != 0 { | ||||
| 			msg.Content.SignedData.Certificates, err = x509.ParseCertificates(signedData.Certificates.Bytes) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 			} | ||||
| 		} | ||||
| 		if len(signedData.Crls.Bytes) != 0 { | ||||
| 			msg.Content.SignedData.Crl, err = x509.ParseDERCRL(signedData.Crls.Bytes) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 			} | ||||
| 		} | ||||
| 		msg.Content.SignedData.Version = signedData.Version | ||||
| 		msg.Content.SignedData.Raw = pkcs7.Content.Bytes | ||||
| 	case msg.ContentInfo == ObjIDEncryptedData: | ||||
| 		msg.ContentInfo = "EncryptedData" | ||||
| 		var encryptedData EncryptedData | ||||
| 		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &encryptedData) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 		} | ||||
| 		if encryptedData.Version != 0 { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for PKCS #7 encryptedData version 0")) | ||||
| 		} | ||||
| 		msg.Content.EncryptedData = encryptedData | ||||
|  | ||||
| 	default: | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Attempt to parse PKCS# 7 Content not of type data, signed data or encrypted data")) | ||||
| 	} | ||||
|  | ||||
| 	return msg, nil | ||||
|  | ||||
| } | ||||
							
								
								
									
										432
									
								
								vendor/github.com/cloudflare/cfssl/csr/csr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								vendor/github.com/cloudflare/cfssl/csr/csr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,432 @@ | ||||
| // Package csr implements certificate requests for CFSSL. | ||||
| package csr | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"net/mail" | ||||
| 	"strings" | ||||
|  | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| 	"github.com/cloudflare/cfssl/log" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	curveP256 = 256 | ||||
| 	curveP384 = 384 | ||||
| 	curveP521 = 521 | ||||
| ) | ||||
|  | ||||
| // A Name contains the SubjectInfo fields. | ||||
| type Name struct { | ||||
| 	C            string // Country | ||||
| 	ST           string // State | ||||
| 	L            string // Locality | ||||
| 	O            string // OrganisationName | ||||
| 	OU           string // OrganisationalUnitName | ||||
| 	SerialNumber string | ||||
| } | ||||
|  | ||||
| // A KeyRequest is a generic request for a new key. | ||||
| type KeyRequest interface { | ||||
| 	Algo() string | ||||
| 	Size() int | ||||
| 	Generate() (crypto.PrivateKey, error) | ||||
| 	SigAlgo() x509.SignatureAlgorithm | ||||
| } | ||||
|  | ||||
| // A BasicKeyRequest contains the algorithm and key size for a new private key. | ||||
| type BasicKeyRequest struct { | ||||
| 	A string `json:"algo" yaml:"algo"` | ||||
| 	S int    `json:"size" yaml:"size"` | ||||
| } | ||||
|  | ||||
| // NewBasicKeyRequest returns a default BasicKeyRequest. | ||||
| func NewBasicKeyRequest() *BasicKeyRequest { | ||||
| 	return &BasicKeyRequest{"ecdsa", curveP256} | ||||
| } | ||||
|  | ||||
| // Algo returns the requested key algorithm represented as a string. | ||||
| func (kr *BasicKeyRequest) Algo() string { | ||||
| 	return kr.A | ||||
| } | ||||
|  | ||||
| // Size returns the requested key size. | ||||
| func (kr *BasicKeyRequest) Size() int { | ||||
| 	return kr.S | ||||
| } | ||||
|  | ||||
| // Generate generates a key as specified in the request. Currently, | ||||
| // only ECDSA and RSA are supported. | ||||
| func (kr *BasicKeyRequest) Generate() (crypto.PrivateKey, error) { | ||||
| 	log.Debugf("generate key from request: algo=%s, size=%d", kr.Algo(), kr.Size()) | ||||
| 	switch kr.Algo() { | ||||
| 	case "rsa": | ||||
| 		if kr.Size() < 2048 { | ||||
| 			return nil, errors.New("RSA key is too weak") | ||||
| 		} | ||||
| 		if kr.Size() > 8192 { | ||||
| 			return nil, errors.New("RSA key size too large") | ||||
| 		} | ||||
| 		return rsa.GenerateKey(rand.Reader, kr.Size()) | ||||
| 	case "ecdsa": | ||||
| 		var curve elliptic.Curve | ||||
| 		switch kr.Size() { | ||||
| 		case curveP256: | ||||
| 			curve = elliptic.P256() | ||||
| 		case curveP384: | ||||
| 			curve = elliptic.P384() | ||||
| 		case curveP521: | ||||
| 			curve = elliptic.P521() | ||||
| 		default: | ||||
| 			return nil, errors.New("invalid curve") | ||||
| 		} | ||||
| 		return ecdsa.GenerateKey(curve, rand.Reader) | ||||
| 	default: | ||||
| 		return nil, errors.New("invalid algorithm") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SigAlgo returns an appropriate X.509 signature algorithm given the | ||||
| // key request's type and size. | ||||
| func (kr *BasicKeyRequest) SigAlgo() x509.SignatureAlgorithm { | ||||
| 	switch kr.Algo() { | ||||
| 	case "rsa": | ||||
| 		switch { | ||||
| 		case kr.Size() >= 4096: | ||||
| 			return x509.SHA512WithRSA | ||||
| 		case kr.Size() >= 3072: | ||||
| 			return x509.SHA384WithRSA | ||||
| 		case kr.Size() >= 2048: | ||||
| 			return x509.SHA256WithRSA | ||||
| 		default: | ||||
| 			return x509.SHA1WithRSA | ||||
| 		} | ||||
| 	case "ecdsa": | ||||
| 		switch kr.Size() { | ||||
| 		case curveP521: | ||||
| 			return x509.ECDSAWithSHA512 | ||||
| 		case curveP384: | ||||
| 			return x509.ECDSAWithSHA384 | ||||
| 		case curveP256: | ||||
| 			return x509.ECDSAWithSHA256 | ||||
| 		default: | ||||
| 			return x509.ECDSAWithSHA1 | ||||
| 		} | ||||
| 	default: | ||||
| 		return x509.UnknownSignatureAlgorithm | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // CAConfig is a section used in the requests initialising a new CA. | ||||
| type CAConfig struct { | ||||
| 	PathLength  int    `json:"pathlen" yaml:"pathlen"` | ||||
| 	PathLenZero bool   `json:"pathlenzero" yaml:"pathlenzero"` | ||||
| 	Expiry      string `json:"expiry" yaml:"expiry"` | ||||
| 	Backdate    string `json:"backdate" yaml:"backdate"` | ||||
| } | ||||
|  | ||||
| // A CertificateRequest encapsulates the API interface to the | ||||
| // certificate request functionality. | ||||
| type CertificateRequest struct { | ||||
| 	CN           string | ||||
| 	Names        []Name     `json:"names" yaml:"names"` | ||||
| 	Hosts        []string   `json:"hosts" yaml:"hosts"` | ||||
| 	KeyRequest   KeyRequest `json:"key,omitempty" yaml:"key,omitempty"` | ||||
| 	CA           *CAConfig  `json:"ca,omitempty" yaml:"ca,omitempty"` | ||||
| 	SerialNumber string     `json:"serialnumber,omitempty" yaml:"serialnumber,omitempty"` | ||||
| } | ||||
|  | ||||
| // New returns a new, empty CertificateRequest with a | ||||
| // BasicKeyRequest. | ||||
| func New() *CertificateRequest { | ||||
| 	return &CertificateRequest{ | ||||
| 		KeyRequest: NewBasicKeyRequest(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // appendIf appends to a if s is not an empty string. | ||||
| func appendIf(s string, a *[]string) { | ||||
| 	if s != "" { | ||||
| 		*a = append(*a, s) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Name returns the PKIX name for the request. | ||||
| func (cr *CertificateRequest) Name() pkix.Name { | ||||
| 	var name pkix.Name | ||||
| 	name.CommonName = cr.CN | ||||
|  | ||||
| 	for _, n := range cr.Names { | ||||
| 		appendIf(n.C, &name.Country) | ||||
| 		appendIf(n.ST, &name.Province) | ||||
| 		appendIf(n.L, &name.Locality) | ||||
| 		appendIf(n.O, &name.Organization) | ||||
| 		appendIf(n.OU, &name.OrganizationalUnit) | ||||
| 	} | ||||
| 	name.SerialNumber = cr.SerialNumber | ||||
| 	return name | ||||
| } | ||||
|  | ||||
| // BasicConstraints CSR information RFC 5280, 4.2.1.9 | ||||
| type BasicConstraints struct { | ||||
| 	IsCA       bool `asn1:"optional"` | ||||
| 	MaxPathLen int  `asn1:"optional,default:-1"` | ||||
| } | ||||
|  | ||||
| // ParseRequest takes a certificate request and generates a key and | ||||
| // CSR from it. It does no validation -- caveat emptor. It will, | ||||
| // however, fail if the key request is not valid (i.e., an unsupported | ||||
| // curve or RSA key size). The lack of validation was specifically | ||||
| // chosen to allow the end user to define a policy and validate the | ||||
| // request appropriately before calling this function. | ||||
| func ParseRequest(req *CertificateRequest) (csr, key []byte, err error) { | ||||
| 	log.Info("received CSR") | ||||
| 	if req.KeyRequest == nil { | ||||
| 		req.KeyRequest = NewBasicKeyRequest() | ||||
| 	} | ||||
|  | ||||
| 	log.Infof("generating key: %s-%d", req.KeyRequest.Algo(), req.KeyRequest.Size()) | ||||
| 	priv, err := req.KeyRequest.Generate() | ||||
| 	if err != nil { | ||||
| 		err = cferr.Wrap(cferr.PrivateKeyError, cferr.GenerationFailed, err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	switch priv := priv.(type) { | ||||
| 	case *rsa.PrivateKey: | ||||
| 		key = x509.MarshalPKCS1PrivateKey(priv) | ||||
| 		block := pem.Block{ | ||||
| 			Type:  "RSA PRIVATE KEY", | ||||
| 			Bytes: key, | ||||
| 		} | ||||
| 		key = pem.EncodeToMemory(&block) | ||||
| 	case *ecdsa.PrivateKey: | ||||
| 		key, err = x509.MarshalECPrivateKey(priv) | ||||
| 		if err != nil { | ||||
| 			err = cferr.Wrap(cferr.PrivateKeyError, cferr.Unknown, err) | ||||
| 			return | ||||
| 		} | ||||
| 		block := pem.Block{ | ||||
| 			Type:  "EC PRIVATE KEY", | ||||
| 			Bytes: key, | ||||
| 		} | ||||
| 		key = pem.EncodeToMemory(&block) | ||||
| 	default: | ||||
| 		panic("Generate should have failed to produce a valid key.") | ||||
| 	} | ||||
|  | ||||
| 	csr, err = Generate(priv.(crypto.Signer), req) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to generate a CSR: %v", err) | ||||
| 		err = cferr.Wrap(cferr.CSRError, cferr.BadRequest, err) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // ExtractCertificateRequest extracts a CertificateRequest from | ||||
| // x509.Certificate. It is aimed to used for generating a new certificate | ||||
| // from an existing certificate. For a root certificate, the CA expiry | ||||
| // length is calculated as the duration between cert.NotAfter and cert.NotBefore. | ||||
| func ExtractCertificateRequest(cert *x509.Certificate) *CertificateRequest { | ||||
| 	req := New() | ||||
| 	req.CN = cert.Subject.CommonName | ||||
| 	req.Names = getNames(cert.Subject) | ||||
| 	req.Hosts = getHosts(cert) | ||||
| 	req.SerialNumber = cert.Subject.SerialNumber | ||||
|  | ||||
| 	if cert.IsCA { | ||||
| 		req.CA = new(CAConfig) | ||||
| 		// CA expiry length is calculated based on the input cert | ||||
| 		// issue date and expiry date. | ||||
| 		req.CA.Expiry = cert.NotAfter.Sub(cert.NotBefore).String() | ||||
| 		req.CA.PathLength = cert.MaxPathLen | ||||
| 		req.CA.PathLenZero = cert.MaxPathLenZero | ||||
| 	} | ||||
|  | ||||
| 	return req | ||||
| } | ||||
|  | ||||
| func getHosts(cert *x509.Certificate) []string { | ||||
| 	var hosts []string | ||||
| 	for _, ip := range cert.IPAddresses { | ||||
| 		hosts = append(hosts, ip.String()) | ||||
| 	} | ||||
| 	for _, dns := range cert.DNSNames { | ||||
| 		hosts = append(hosts, dns) | ||||
| 	} | ||||
| 	for _, email := range cert.EmailAddresses { | ||||
| 		hosts = append(hosts, email) | ||||
| 	} | ||||
|  | ||||
| 	return hosts | ||||
| } | ||||
|  | ||||
| // getNames returns an array of Names from the certificate | ||||
| // It onnly cares about Country, Organization, OrganizationalUnit, Locality, Province | ||||
| func getNames(sub pkix.Name) []Name { | ||||
| 	// anonymous func for finding the max of a list of interger | ||||
| 	max := func(v1 int, vn ...int) (max int) { | ||||
| 		max = v1 | ||||
| 		for i := 0; i < len(vn); i++ { | ||||
| 			if vn[i] > max { | ||||
| 				max = vn[i] | ||||
| 			} | ||||
| 		} | ||||
| 		return max | ||||
| 	} | ||||
|  | ||||
| 	nc := len(sub.Country) | ||||
| 	norg := len(sub.Organization) | ||||
| 	nou := len(sub.OrganizationalUnit) | ||||
| 	nl := len(sub.Locality) | ||||
| 	np := len(sub.Province) | ||||
|  | ||||
| 	n := max(nc, norg, nou, nl, np) | ||||
|  | ||||
| 	names := make([]Name, n) | ||||
| 	for i := range names { | ||||
| 		if i < nc { | ||||
| 			names[i].C = sub.Country[i] | ||||
| 		} | ||||
| 		if i < norg { | ||||
| 			names[i].O = sub.Organization[i] | ||||
| 		} | ||||
| 		if i < nou { | ||||
| 			names[i].OU = sub.OrganizationalUnit[i] | ||||
| 		} | ||||
| 		if i < nl { | ||||
| 			names[i].L = sub.Locality[i] | ||||
| 		} | ||||
| 		if i < np { | ||||
| 			names[i].ST = sub.Province[i] | ||||
| 		} | ||||
| 	} | ||||
| 	return names | ||||
| } | ||||
|  | ||||
| // A Generator is responsible for validating certificate requests. | ||||
| type Generator struct { | ||||
| 	Validator func(*CertificateRequest) error | ||||
| } | ||||
|  | ||||
| // ProcessRequest validates and processes the incoming request. It is | ||||
| // a wrapper around a validator and the ParseRequest function. | ||||
| func (g *Generator) ProcessRequest(req *CertificateRequest) (csr, key []byte, err error) { | ||||
|  | ||||
| 	log.Info("generate received request") | ||||
| 	err = g.Validator(req) | ||||
| 	if err != nil { | ||||
| 		log.Warningf("invalid request: %v", err) | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | ||||
| 	csr, key, err = ParseRequest(req) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // IsNameEmpty returns true if the name has no identifying information in it. | ||||
| func IsNameEmpty(n Name) bool { | ||||
| 	empty := func(s string) bool { return strings.TrimSpace(s) == "" } | ||||
|  | ||||
| 	if empty(n.C) && empty(n.ST) && empty(n.L) && empty(n.O) && empty(n.OU) { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Regenerate uses the provided CSR as a template for signing a new | ||||
| // CSR using priv. | ||||
| func Regenerate(priv crypto.Signer, csr []byte) ([]byte, error) { | ||||
| 	req, extra, err := helpers.ParseCSR(csr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} else if len(extra) > 0 { | ||||
| 		return nil, errors.New("csr: trailing data in certificate request") | ||||
| 	} | ||||
|  | ||||
| 	return x509.CreateCertificateRequest(rand.Reader, req, priv) | ||||
| } | ||||
|  | ||||
| // Generate creates a new CSR from a CertificateRequest structure and | ||||
| // an existing key. The KeyRequest field is ignored. | ||||
| func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err error) { | ||||
| 	sigAlgo := helpers.SignerAlgo(priv) | ||||
| 	if sigAlgo == x509.UnknownSignatureAlgorithm { | ||||
| 		return nil, cferr.New(cferr.PrivateKeyError, cferr.Unavailable) | ||||
| 	} | ||||
|  | ||||
| 	var tpl = x509.CertificateRequest{ | ||||
| 		Subject:            req.Name(), | ||||
| 		SignatureAlgorithm: sigAlgo, | ||||
| 	} | ||||
|  | ||||
| 	for i := range req.Hosts { | ||||
| 		if ip := net.ParseIP(req.Hosts[i]); ip != nil { | ||||
| 			tpl.IPAddresses = append(tpl.IPAddresses, ip) | ||||
| 		} else if email, err := mail.ParseAddress(req.Hosts[i]); err == nil && email != nil { | ||||
| 			tpl.EmailAddresses = append(tpl.EmailAddresses, email.Address) | ||||
| 		} else { | ||||
| 			tpl.DNSNames = append(tpl.DNSNames, req.Hosts[i]) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if req.CA != nil { | ||||
| 		err = appendCAInfoToCSR(req.CA, &tpl) | ||||
| 		if err != nil { | ||||
| 			err = cferr.Wrap(cferr.CSRError, cferr.GenerationFailed, err) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	csr, err = x509.CreateCertificateRequest(rand.Reader, &tpl, priv) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to generate a CSR: %v", err) | ||||
| 		err = cferr.Wrap(cferr.CSRError, cferr.BadRequest, err) | ||||
| 		return | ||||
| 	} | ||||
| 	block := pem.Block{ | ||||
| 		Type:  "CERTIFICATE REQUEST", | ||||
| 		Bytes: csr, | ||||
| 	} | ||||
|  | ||||
| 	log.Info("encoded CSR") | ||||
| 	csr = pem.EncodeToMemory(&block) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // appendCAInfoToCSR appends CAConfig BasicConstraint extension to a CSR | ||||
| func appendCAInfoToCSR(reqConf *CAConfig, csr *x509.CertificateRequest) error { | ||||
| 	pathlen := reqConf.PathLength | ||||
| 	if pathlen == 0 && !reqConf.PathLenZero { | ||||
| 		pathlen = -1 | ||||
| 	} | ||||
| 	val, err := asn1.Marshal(BasicConstraints{true, pathlen}) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	csr.ExtraExtensions = []pkix.Extension{ | ||||
| 		{ | ||||
| 			Id:       asn1.ObjectIdentifier{2, 5, 29, 19}, | ||||
| 			Value:    val, | ||||
| 			Critical: true, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										744
									
								
								vendor/github.com/cloudflare/cfssl/csr/csr_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										744
									
								
								vendor/github.com/cloudflare/cfssl/csr/csr_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,744 @@ | ||||
| package csr | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/pem" | ||||
| 	"io/ioutil" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| ) | ||||
|  | ||||
| //TestNew validate the CertificateRequest created to return with a BasicKeyRequest | ||||
| //in KeyRequest field | ||||
|  | ||||
| func TestNew(t *testing.T) { | ||||
|  | ||||
| 	if cr := New(); cr.KeyRequest == nil { | ||||
| 		t.Fatalf("Should create a new, empty certificate request with BasicKeyRequest") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestBasicKeyRequest ensures that key generation returns the same type of | ||||
| // key specified in the BasicKeyRequest. | ||||
| func TestBasicKeyRequest(t *testing.T) { | ||||
| 	kr := NewBasicKeyRequest() | ||||
| 	priv, err := kr.Generate() | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	switch priv.(type) { | ||||
| 	case *rsa.PrivateKey: | ||||
| 		if kr.Algo() != "rsa" { | ||||
| 			t.Fatal("RSA key generated, but expected", kr.Algo()) | ||||
| 		} | ||||
| 	case *ecdsa.PrivateKey: | ||||
| 		if kr.Algo() != "ecdsa" { | ||||
| 			t.Fatal("ECDSA key generated, but expected", kr.Algo()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestPKIXName validates building a pkix.Name structure from a | ||||
| // CertificateRequest. | ||||
| func TestPKIXName(t *testing.T) { | ||||
| 	var cr = &CertificateRequest{ | ||||
| 		CN: "Test Common Name", | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare, Inc.", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 			{ | ||||
| 				C:  "GB", | ||||
| 				ST: "London", | ||||
| 				L:  "London", | ||||
| 				O:  "CloudFlare, Inc", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com"}, | ||||
| 		KeyRequest: NewBasicKeyRequest(), | ||||
| 	} | ||||
|  | ||||
| 	name := cr.Name() | ||||
| 	if len(name.Country) != 2 { | ||||
| 		t.Fatal("Expected two countries in SubjInfo.") | ||||
| 	} else if len(name.Province) != 2 { | ||||
| 		t.Fatal("Expected two states in SubjInfo.") | ||||
| 	} else if len(name.Locality) != 2 { | ||||
| 		t.Fatal("Expected two localities in SubjInfo.") | ||||
| 	} else if len(name.Country) != 2 { | ||||
| 		t.Fatal("Expected two countries in SubjInfo.") | ||||
| 	} else if len(name.Organization) != 2 { | ||||
| 		t.Fatal("Expected two organization in SubjInfo.") | ||||
| 	} else if len(name.OrganizationalUnit) != 2 { | ||||
| 		t.Fatal("Expected two organizational units in SubjInfo.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestParseRequest ensures that a valid certificate request does not | ||||
| // error. | ||||
| func TestParseRequest(t *testing.T) { | ||||
| 	var cr = &CertificateRequest{ | ||||
| 		CN: "Test Common Name", | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare, Inc.", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 			{ | ||||
| 				C:  "GB", | ||||
| 				ST: "London", | ||||
| 				L:  "London", | ||||
| 				O:  "CloudFlare, Inc", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1", "jdoe@example.com"}, | ||||
| 		KeyRequest: NewBasicKeyRequest(), | ||||
| 	} | ||||
|  | ||||
| 	_, _, err := ParseRequest(cr) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestParseRequestCA ensures that a valid CA certificate request does not | ||||
| // error and the resulting CSR includes the BasicConstraint extension | ||||
| func TestParseRequestCA(t *testing.T) { | ||||
| 	var cr = &CertificateRequest{ | ||||
| 		CN: "Test Common Name", | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare, Inc.", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 			{ | ||||
| 				C:  "GB", | ||||
| 				ST: "London", | ||||
| 				L:  "London", | ||||
| 				O:  "CloudFlare, Inc", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CA: &CAConfig{ | ||||
| 			PathLength:  0, | ||||
| 			PathLenZero: true, | ||||
| 		}, | ||||
| 		KeyRequest: NewBasicKeyRequest(), | ||||
| 	} | ||||
|  | ||||
| 	csrBytes, _, err := ParseRequest(cr) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	block, _ := pem.Decode(csrBytes) | ||||
| 	if block == nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if block.Type != "CERTIFICATE REQUEST" { | ||||
| 		t.Fatalf("Incorrect block type: %s", block.Type) | ||||
| 	} | ||||
|  | ||||
| 	csr, err := x509.ParseCertificateRequest(block.Bytes) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	found := false | ||||
| 	for _, ext := range csr.Extensions { | ||||
| 		if ext.Id.Equal(asn1.ObjectIdentifier{2, 5, 29, 19}) { | ||||
| 			found = true | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !found { | ||||
| 		t.Fatalf("CSR did not include BasicConstraint Extension") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestParseRequestCANoPathlen ensures that a valid CA certificate request | ||||
| // with an unspecified pathlen does not error and the resulting CSR includes | ||||
| // the BasicConstraint extension | ||||
| func TestParseRequestCANoPathlen(t *testing.T) { | ||||
| 	var cr = &CertificateRequest{ | ||||
| 		CN: "Test Common Name", | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare, Inc.", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 			{ | ||||
| 				C:  "GB", | ||||
| 				ST: "London", | ||||
| 				L:  "London", | ||||
| 				O:  "CloudFlare, Inc", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CA: &CAConfig{ | ||||
| 			PathLength:  0, | ||||
| 			PathLenZero: false, | ||||
| 		}, | ||||
| 		KeyRequest: NewBasicKeyRequest(), | ||||
| 	} | ||||
|  | ||||
| 	csrBytes, _, err := ParseRequest(cr) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	block, _ := pem.Decode(csrBytes) | ||||
| 	if block == nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if block.Type != "CERTIFICATE REQUEST" { | ||||
| 		t.Fatalf("Incorrect block type: %s", block.Type) | ||||
| 	} | ||||
|  | ||||
| 	csr, err := x509.ParseCertificateRequest(block.Bytes) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	found := false | ||||
| 	for _, ext := range csr.Extensions { | ||||
| 		if ext.Id.Equal(asn1.ObjectIdentifier{2, 5, 29, 19}) { | ||||
| 			bc := &BasicConstraints{} | ||||
| 			asn1.Unmarshal(ext.Value, bc) | ||||
| 			if bc.IsCA == true && bc.MaxPathLen == -1 { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !found { | ||||
| 		t.Fatalf("CSR did not include BasicConstraint Extension") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func whichCurve(sz int) elliptic.Curve { | ||||
| 	switch sz { | ||||
| 	case 256: | ||||
| 		return elliptic.P256() | ||||
| 	case 384: | ||||
| 		return elliptic.P384() | ||||
| 	case 521: | ||||
| 		return elliptic.P521() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // TestECGeneration ensures that the proper curve is used depending on | ||||
| // the bit size specified in a key request and that an appropriate | ||||
| // signature algorithm is returned. | ||||
| func TestECGeneration(t *testing.T) { | ||||
| 	var eckey *ecdsa.PrivateKey | ||||
|  | ||||
| 	for _, sz := range []int{256, 384, 521} { | ||||
| 		kr := &BasicKeyRequest{"ecdsa", sz} | ||||
| 		priv, err := kr.Generate() | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("%v", err) | ||||
| 		} | ||||
| 		eckey = priv.(*ecdsa.PrivateKey) | ||||
| 		if eckey.Curve != whichCurve(sz) { | ||||
| 			t.Fatal("Generated key has wrong curve.") | ||||
| 		} | ||||
| 		if sa := kr.SigAlgo(); sa == x509.UnknownSignatureAlgorithm { | ||||
| 			t.Fatal("Invalid signature algorithm!") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRSAKeyGeneration(t *testing.T) { | ||||
| 	var rsakey *rsa.PrivateKey | ||||
|  | ||||
| 	for _, sz := range []int{2048, 3072, 4096} { | ||||
| 		kr := &BasicKeyRequest{"rsa", sz} | ||||
| 		priv, err := kr.Generate() | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("%v", err) | ||||
| 		} | ||||
| 		rsakey = priv.(*rsa.PrivateKey) | ||||
| 		if rsakey.PublicKey.N.BitLen() != kr.Size() { | ||||
| 			t.Fatal("Generated key has wrong size.") | ||||
| 		} | ||||
| 		if sa := kr.SigAlgo(); sa == x509.UnknownSignatureAlgorithm { | ||||
| 			t.Fatal("Invalid signature algorithm!") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestBadBasicKeyRequest ensures that generating a key from a BasicKeyRequest | ||||
| // fails with an invalid algorithm, or an invalid RSA or ECDSA key | ||||
| // size. An invalid ECDSA key size is any size other than 256, 384, or | ||||
| // 521; an invalid RSA key size is any size less than 2048 bits. | ||||
| func TestBadBasicKeyRequest(t *testing.T) { | ||||
| 	kr := &BasicKeyRequest{"yolocrypto", 1024} | ||||
|  | ||||
| 	if _, err := kr.Generate(); err == nil { | ||||
| 		t.Fatal("Key generation should fail with invalid algorithm") | ||||
| 	} else if sa := kr.SigAlgo(); sa != x509.UnknownSignatureAlgorithm { | ||||
| 		t.Fatal("The wrong signature algorithm was returned from SigAlgo!") | ||||
| 	} | ||||
|  | ||||
| 	kr.A = "ecdsa" | ||||
| 	if _, err := kr.Generate(); err == nil { | ||||
| 		t.Fatal("Key generation should fail with invalid key size") | ||||
| 	} else if sa := kr.SigAlgo(); sa != x509.ECDSAWithSHA1 { | ||||
| 		t.Fatal("The wrong signature algorithm was returned from SigAlgo!") | ||||
| 	} | ||||
|  | ||||
| 	kr.A = "rsa" | ||||
| 	if _, err := kr.Generate(); err == nil { | ||||
| 		t.Fatal("Key generation should fail with invalid key size") | ||||
| 	} else if sa := kr.SigAlgo(); sa != x509.SHA1WithRSA { | ||||
| 		t.Fatal("The wrong signature algorithm was returned from SigAlgo!") | ||||
| 	} | ||||
|  | ||||
| 	kr = &BasicKeyRequest{"tobig", 9216} | ||||
|  | ||||
| 	kr.A = "rsa" | ||||
| 	if _, err := kr.Generate(); err == nil { | ||||
| 		t.Fatal("Key generation should fail with invalid key size") | ||||
| 	} else if sa := kr.SigAlgo(); sa != x509.SHA512WithRSA { | ||||
| 		t.Fatal("The wrong signature algorithm was returned from SigAlgo!") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestDefaultBasicKeyRequest makes sure that certificate requests without | ||||
| // explicit key requests fall back to the default key request. | ||||
| func TestDefaultBasicKeyRequest(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:    "cloudflare.com", | ||||
| 		Hosts: []string{"cloudflare.com", "www.cloudflare.com", "jdoe@example.com"}, | ||||
| 	} | ||||
| 	_, priv, err := ParseRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	// If the default key type changes, this will need to be changed. | ||||
| 	block, _ := pem.Decode(priv) | ||||
| 	if block == nil { | ||||
| 		t.Fatal("Bad private key was generated!") | ||||
| 	} | ||||
|  | ||||
| 	DefaultKeyRequest := NewBasicKeyRequest() | ||||
| 	switch block.Type { | ||||
| 	case "RSA PRIVATE KEY": | ||||
| 		if DefaultKeyRequest.Algo() != "rsa" { | ||||
| 			t.Fatal("Invalid default key request.") | ||||
| 		} | ||||
| 	case "EC PRIVATE KEY": | ||||
| 		if DefaultKeyRequest.Algo() != "ecdsa" { | ||||
| 			t.Fatal("Invalid default key request.") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestRSACertRequest validates parsing a certificate request with an | ||||
| // RSA key. | ||||
| func TestRSACertRequest(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "jdoe@example.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"rsa", 2048}, | ||||
| 	} | ||||
| 	_, _, err := ParseRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestBadCertRequest checks for failure conditions of ParseRequest. | ||||
| func TestBadCertRequest(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"yolo-crypto", 2048}, | ||||
| 	} | ||||
| 	_, _, err := ParseRequest(req) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("ParseRequest should fail with a bad key algorithm.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // testValidator is a stripped-down validator that checks to make sure | ||||
| // the request has a common name. It should mimic some of the | ||||
| // functionality expected in an actual validator. | ||||
| func testValidator(req *CertificateRequest) error { | ||||
| 	if req.CN == "" { | ||||
| 		return errors.NewBadRequestMissingParameter("CN") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // TestGenerator ensures that a valid request is processed properly | ||||
| // and returns a certificate request and key. | ||||
| func TestGenerator(t *testing.T) { | ||||
| 	g := &Generator{testValidator} | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1", "jdoe@example.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"rsa", 2048}, | ||||
| 	} | ||||
|  | ||||
| 	csrBytes, _, err := g.ProcessRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	block, _ := pem.Decode([]byte(csrBytes)) | ||||
| 	if block == nil { | ||||
| 		t.Fatalf("bad CSR in PEM") | ||||
| 	} | ||||
|  | ||||
| 	if block.Type != "CERTIFICATE REQUEST" { | ||||
| 		t.Fatalf("bad CSR in PEM") | ||||
| 	} | ||||
|  | ||||
| 	csr, err := x509.ParseCertificateRequest(block.Bytes) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.DNSNames) != 2 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.IPAddresses) != 1 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.EmailAddresses) != 1 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| // TestBadGenerator ensures that a request that fails the validator is | ||||
| // not processed. | ||||
| func TestBadGenerator(t *testing.T) { | ||||
| 	g := &Generator{testValidator} | ||||
| 	missingCN := &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		// Missing CN | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"rsa", 2048}, | ||||
| 	} | ||||
|  | ||||
| 	_, _, err := g.ProcessRequest(missingCN) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("Request should have failed.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestWeakCSR(t *testing.T) { | ||||
| 	weakKey := &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "jdoe@example.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"rsa", 1024}, | ||||
| 	} | ||||
| 	g := &Generator{testValidator} | ||||
|  | ||||
| 	_, _, err := g.ProcessRequest(weakKey) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("Request should have failed.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var testEmpty = []struct { | ||||
| 	name Name | ||||
| 	ok   bool | ||||
| }{ | ||||
| 	{ | ||||
| 		Name{}, | ||||
| 		true, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name{C: "OK"}, | ||||
| 		false, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name{ST: "OK"}, | ||||
| 		false, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name{L: "OK"}, | ||||
| 		false, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name{O: "OK"}, | ||||
| 		false, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name{OU: "OK"}, | ||||
| 		false, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| func TestIsNameEmpty(t *testing.T) { | ||||
| 	for i, c := range testEmpty { | ||||
| 		if IsNameEmpty(c.name) != c.ok { | ||||
| 			t.Fatalf("%d: expected IsNameEmpty to return %v, but have %v", i, c.ok, !c.ok) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestGenerate(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1", "jdoe@example.com"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"ecdsa", 256}, | ||||
| 	} | ||||
|  | ||||
| 	key, err := req.KeyRequest.Generate() | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	priv, ok := key.(crypto.Signer) | ||||
| 	if !ok { | ||||
| 		t.Fatal("Private key is not a signer.") | ||||
| 	} | ||||
|  | ||||
| 	csrPEM, err := Generate(priv, req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	csr, _, err := helpers.ParseCSR(csrPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.DNSNames) != 2 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.IPAddresses) != 1 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
|  | ||||
| 	if len(csr.EmailAddresses) != 1 { | ||||
| 		t.Fatal("SAN parsing error") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestReGenerate ensures Regenerate() is abel to use the provided CSR as a template for signing a new | ||||
| // CSR using priv. | ||||
| func TestReGenerate(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"ecdsa", 256}, | ||||
| 	} | ||||
|  | ||||
| 	_, key, err := ParseRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEM(key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	csr, err := Generate(priv, req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	if _, _, err = helpers.ParseCSR(csr); err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	_, err = Regenerate(priv, csr) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestBadReGenerator ensures that a request that fails the ParseCSR is | ||||
| // not processed. | ||||
| func TestBadReGenerate(t *testing.T) { | ||||
| 	var req = &CertificateRequest{ | ||||
| 		Names: []Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         "cloudflare.com", | ||||
| 		Hosts:      []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1"}, | ||||
| 		KeyRequest: &BasicKeyRequest{"ecdsa", 256}, | ||||
| 	} | ||||
|  | ||||
| 	_, key, err := ParseRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEM(key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	csr, err := Generate(priv, req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	block := pem.Block{ | ||||
| 		Type: "CERTIFICATE REQUEST", | ||||
| 		Headers: map[string]string{ | ||||
| 			"Location": "UCSD", | ||||
| 		}, | ||||
| 		Bytes: csr, | ||||
| 	} | ||||
|  | ||||
| 	csr = pem.EncodeToMemory(&block) | ||||
|  | ||||
| 	_, err = Regenerate(priv, csr) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var testECDSACertificateFile = "testdata/test-ecdsa-ca.pem" | ||||
|  | ||||
| func TestExtractCertificateRequest(t *testing.T) { | ||||
| 	certPEM, err := ioutil.ReadFile(testECDSACertificateFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// must parse ok | ||||
| 	cert, err := helpers.ParseCertificatePEM(certPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	req := ExtractCertificateRequest(cert) | ||||
|  | ||||
| 	if req.CN != "" { | ||||
| 		t.Fatal("Bad Certificate Request!") | ||||
| 	} | ||||
|  | ||||
| 	if len(req.Names) != 1 { | ||||
| 		t.Fatal("Bad Certificate Request!") | ||||
| 	} | ||||
|  | ||||
| 	name := req.Names[0] | ||||
| 	if name.C != "US" || name.ST != "California" || name.O != "CloudFlare, Inc." || | ||||
| 		name.OU != "Test Certificate Authority" || name.L != "San Francisco" { | ||||
| 		t.Fatal("Bad Certificate Request!") | ||||
| 	} | ||||
|  | ||||
| 	if req.CA == nil || req.CA.PathLength != 2 { | ||||
| 		t.Fatal("Bad Certificate Request!") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/csr/testdata/test-ecdsa-ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/csr/testdata/test-ecdsa-ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIICUDCCAfagAwIBAgIIec5PjdpJcNYwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMC | ||||
| VVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAhBgNVBAsTGlRlc3QgQ2Vy | ||||
| dGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYD | ||||
| VQQIEwpDYWxpZm9ybmlhMB4XDTE1MTAwODIzMDEwMFoXDTE1MTAwODIzMDYwMFow | ||||
| ejELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAhBgNV | ||||
| BAsTGlRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMFkwEwYHKoZIzj0CAQYIKoZIzj0D | ||||
| AQcDQgAEoCV+bVOLTJMy38j50sc3vE5k41GMRgriFJt0g0OVX8yaOZ93CZTI7Lzf | ||||
| GbMU+KqWTgOwGhrPvpusep3fjw+dAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1Ud | ||||
| EwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFDpLhSKBN3njfb6cXQCdRLzCZt0ZMB8G | ||||
| A1UdIwQYMBaAFDpLhSKBN3njfb6cXQCdRLzCZt0ZMAoGCCqGSM49BAMCA0gAMEUC | ||||
| IFU3BmzntGGeXZu2qWZx249nYn37S0AkCnQ3rUtI31bdAiEAsPICnZ+GB8yCN26N | ||||
| OL+N8dHvXiOvZ9/Vl488pyWOccY= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										46
									
								
								vendor/github.com/cloudflare/cfssl/errors/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/cloudflare/cfssl/errors/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| /* | ||||
| Package errors provides error types returned in CF SSL. | ||||
|  | ||||
| 1. Type Error is intended for errors produced by CF SSL packages. | ||||
| It formats to a json object that consists of an error message and a 4-digit code for error reasoning. | ||||
|  | ||||
| Example: {"code":1002, "message": "Failed to decode certificate"} | ||||
|  | ||||
| The index of codes are listed below: | ||||
| 	1XXX: CertificateError | ||||
| 	    1000: Unknown | ||||
| 	    1001: ReadFailed | ||||
| 	    1002: DecodeFailed | ||||
| 	    1003: ParseFailed | ||||
| 	    1100: SelfSigned | ||||
| 	    12XX: VerifyFailed | ||||
| 	        121X: CertificateInvalid | ||||
| 	            1210: NotAuthorizedToSign | ||||
| 	            1211: Expired | ||||
| 	            1212: CANotAuthorizedForThisName | ||||
| 	            1213: TooManyIntermediates | ||||
| 	            1214: IncompatibleUsage | ||||
| 	        1220: UnknownAuthority | ||||
| 	2XXX: PrivatekeyError | ||||
| 	    2000: Unknown | ||||
| 	    2001: ReadFailed | ||||
| 	    2002: DecodeFailed | ||||
| 	    2003: ParseFailed | ||||
| 	    2100: Encrypted | ||||
| 	    2200: NotRSA | ||||
| 	    2300: KeyMismatch | ||||
| 	    2400: GenerationFailed | ||||
| 	    2500: Unavailable | ||||
| 	3XXX: IntermediatesError | ||||
| 	4XXX: RootError | ||||
| 	5XXX: PolicyError | ||||
| 	    5100: NoKeyUsages | ||||
| 	    5200: InvalidPolicy | ||||
| 	    5300: InvalidRequest | ||||
| 	    5400: UnknownProfile | ||||
| 	    6XXX: DialError | ||||
|  | ||||
| 2. Type HttpError is intended for CF SSL API to consume. It contains a HTTP status code that will be read and returned | ||||
| by the API server. | ||||
| */ | ||||
| package errors | ||||
							
								
								
									
										438
									
								
								vendor/github.com/cloudflare/cfssl/errors/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										438
									
								
								vendor/github.com/cloudflare/cfssl/errors/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,438 @@ | ||||
| package errors | ||||
|  | ||||
| import ( | ||||
| 	"crypto/x509" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| // Error is the error type usually returned by functions in CF SSL package. | ||||
| // It contains a 4-digit error code where the most significant digit | ||||
| // describes the category where the error occurred and the rest 3 digits | ||||
| // describe the specific error reason. | ||||
| type Error struct { | ||||
| 	ErrorCode int    `json:"code"` | ||||
| 	Message   string `json:"message"` | ||||
| } | ||||
|  | ||||
| // Category is the most significant digit of the error code. | ||||
| type Category int | ||||
|  | ||||
| // Reason is the last 3 digits of the error code. | ||||
| type Reason int | ||||
|  | ||||
| const ( | ||||
| 	// Success indicates no error occurred. | ||||
| 	Success Category = 1000 * iota // 0XXX | ||||
|  | ||||
| 	// CertificateError indicates a fault in a certificate. | ||||
| 	CertificateError // 1XXX | ||||
|  | ||||
| 	// PrivateKeyError indicates a fault in a private key. | ||||
| 	PrivateKeyError // 2XXX | ||||
|  | ||||
| 	// IntermediatesError indicates a fault in an intermediate. | ||||
| 	IntermediatesError // 3XXX | ||||
|  | ||||
| 	// RootError indicates a fault in a root. | ||||
| 	RootError // 4XXX | ||||
|  | ||||
| 	// PolicyError indicates an error arising from a malformed or | ||||
| 	// non-existent policy, or a breach of policy. | ||||
| 	PolicyError // 5XXX | ||||
|  | ||||
| 	// DialError indicates a network fault. | ||||
| 	DialError // 6XXX | ||||
|  | ||||
| 	// APIClientError indicates a problem with the API client. | ||||
| 	APIClientError // 7XXX | ||||
|  | ||||
| 	// OCSPError indicates a problem with OCSP signing | ||||
| 	OCSPError // 8XXX | ||||
|  | ||||
| 	// CSRError indicates a problem with CSR parsing | ||||
| 	CSRError // 9XXX | ||||
|  | ||||
| 	// CTError indicates a problem with the certificate transparency process | ||||
| 	CTError // 10XXX | ||||
|  | ||||
| 	// CertStoreError indicates a problem with the certificate store | ||||
| 	CertStoreError // 11XXX | ||||
| ) | ||||
|  | ||||
| // None is a non-specified error. | ||||
| const ( | ||||
| 	None Reason = iota | ||||
| ) | ||||
|  | ||||
| // Warning code for a success | ||||
| const ( | ||||
| 	BundleExpiringBit      int = 1 << iota // 0x01 | ||||
| 	BundleNotUbiquitousBit                 // 0x02 | ||||
| ) | ||||
|  | ||||
| // Parsing errors | ||||
| const ( | ||||
| 	Unknown      Reason = iota // X000 | ||||
| 	ReadFailed                 // X001 | ||||
| 	DecodeFailed               // X002 | ||||
| 	ParseFailed                // X003 | ||||
| ) | ||||
|  | ||||
| // The following represent certificate non-parsing errors, and must be | ||||
| // specified along with CertificateError. | ||||
| const ( | ||||
| 	// SelfSigned indicates that a certificate is self-signed and | ||||
| 	// cannot be used in the manner being attempted. | ||||
| 	SelfSigned Reason = 100 * (iota + 1) // Code 11XX | ||||
|  | ||||
| 	// VerifyFailed is an X.509 verification failure. The least two | ||||
| 	// significant digits of 12XX is determined as the actual x509 | ||||
| 	// error is examined. | ||||
| 	VerifyFailed // Code 12XX | ||||
|  | ||||
| 	// BadRequest indicates that the certificate request is invalid. | ||||
| 	BadRequest // Code 13XX | ||||
|  | ||||
| 	// MissingSerial indicates that the profile specified | ||||
| 	// 'ClientProvidesSerialNumbers', but the SignRequest did not include a serial | ||||
| 	// number. | ||||
| 	MissingSerial // Code 14XX | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	certificateInvalid = 10 * (iota + 1) //121X | ||||
| 	unknownAuthority                     //122x | ||||
| ) | ||||
|  | ||||
| // The following represent private-key non-parsing errors, and must be | ||||
| // specified with PrivateKeyError. | ||||
| const ( | ||||
| 	// Encrypted indicates that the private key is a PKCS #8 encrypted | ||||
| 	// private key. At this time, CFSSL does not support decrypting | ||||
| 	// these keys. | ||||
| 	Encrypted Reason = 100 * (iota + 1) //21XX | ||||
|  | ||||
| 	// NotRSAOrECC indicates that they key is not an RSA or ECC | ||||
| 	// private key; these are the only two private key types supported | ||||
| 	// at this time by CFSSL. | ||||
| 	NotRSAOrECC //22XX | ||||
|  | ||||
| 	// KeyMismatch indicates that the private key does not match | ||||
| 	// the public key or certificate being presented with the key. | ||||
| 	KeyMismatch //23XX | ||||
|  | ||||
| 	// GenerationFailed indicates that a private key could not | ||||
| 	// be generated. | ||||
| 	GenerationFailed //24XX | ||||
|  | ||||
| 	// Unavailable indicates that a private key mechanism (such as | ||||
| 	// PKCS #11) was requested but support for that mechanism is | ||||
| 	// not available. | ||||
| 	Unavailable | ||||
| ) | ||||
|  | ||||
| // The following are policy-related non-parsing errors, and must be | ||||
| // specified along with PolicyError. | ||||
| const ( | ||||
| 	// NoKeyUsages indicates that the profile does not permit any | ||||
| 	// key usages for the certificate. | ||||
| 	NoKeyUsages Reason = 100 * (iota + 1) // 51XX | ||||
|  | ||||
| 	// InvalidPolicy indicates that policy being requested is not | ||||
| 	// a valid policy or does not exist. | ||||
| 	InvalidPolicy // 52XX | ||||
|  | ||||
| 	// InvalidRequest indicates a certificate request violated the | ||||
| 	// constraints of the policy being applied to the request. | ||||
| 	InvalidRequest // 53XX | ||||
|  | ||||
| 	// UnknownProfile indicates that the profile does not exist. | ||||
| 	UnknownProfile // 54XX | ||||
|  | ||||
| 	UnmatchedWhitelist // 55xx | ||||
| ) | ||||
|  | ||||
| // The following are API client related errors, and should be | ||||
| // specified with APIClientError. | ||||
| const ( | ||||
| 	// AuthenticationFailure occurs when the client is unable | ||||
| 	// to obtain an authentication token for the request. | ||||
| 	AuthenticationFailure Reason = 100 * (iota + 1) | ||||
|  | ||||
| 	// JSONError wraps an encoding/json error. | ||||
| 	JSONError | ||||
|  | ||||
| 	// IOError wraps an io/ioutil error. | ||||
| 	IOError | ||||
|  | ||||
| 	// ClientHTTPError wraps a net/http error. | ||||
| 	ClientHTTPError | ||||
|  | ||||
| 	// ServerRequestFailed covers any other failures from the API | ||||
| 	// client. | ||||
| 	ServerRequestFailed | ||||
| ) | ||||
|  | ||||
| // The following are OCSP related errors, and should be | ||||
| // specified with OCSPError | ||||
| const ( | ||||
| 	// IssuerMismatch ocurs when the certificate in the OCSP signing | ||||
| 	// request was not issued by the CA that this responder responds for. | ||||
| 	IssuerMismatch Reason = 100 * (iota + 1) // 81XX | ||||
|  | ||||
| 	// InvalidStatus occurs when the OCSP signing requests includes an | ||||
| 	// invalid value for the certificate status. | ||||
| 	InvalidStatus | ||||
| ) | ||||
|  | ||||
| // Certificate transparency related errors specified with CTError | ||||
| const ( | ||||
| 	// PrecertSubmissionFailed occurs when submitting a precertificate to | ||||
| 	// a log server fails | ||||
| 	PrecertSubmissionFailed = 100 * (iota + 1) | ||||
| 	// CTClientConstructionFailed occurs when the construction of a new | ||||
| 	// github.com/google/certificate-transparency client fails. | ||||
| 	CTClientConstructionFailed | ||||
| 	// PrecertMissingPoison occurs when a precert is passed to SignFromPrecert | ||||
| 	// and is missing the CT poison extension. | ||||
| 	PrecertMissingPoison | ||||
| 	// PrecertInvalidPoison occurs when a precert is passed to SignFromPrecert | ||||
| 	// and has a invalid CT poison extension value or the extension is not | ||||
| 	// critical. | ||||
| 	PrecertInvalidPoison | ||||
| ) | ||||
|  | ||||
| // Certificate persistence related errors specified with CertStoreError | ||||
| const ( | ||||
| 	// InsertionFailed occurs when a SQL insert query failes to complete. | ||||
| 	InsertionFailed = 100 * (iota + 1) | ||||
| 	// RecordNotFound occurs when a SQL query targeting on one unique | ||||
| 	// record failes to update the specified row in the table. | ||||
| 	RecordNotFound | ||||
| ) | ||||
|  | ||||
| // The error interface implementation, which formats to a JSON object string. | ||||
| func (e *Error) Error() string { | ||||
| 	marshaled, err := json.Marshal(e) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return string(marshaled) | ||||
|  | ||||
| } | ||||
|  | ||||
| // New returns an error that contains  an error code and message derived from | ||||
| // the given category, reason. Currently, to avoid confusion, it is not | ||||
| // allowed to create an error of category Success | ||||
| func New(category Category, reason Reason) *Error { | ||||
| 	errorCode := int(category) + int(reason) | ||||
| 	var msg string | ||||
| 	switch category { | ||||
| 	case OCSPError: | ||||
| 		switch reason { | ||||
| 		case ReadFailed: | ||||
| 			msg = "No certificate provided" | ||||
| 		case IssuerMismatch: | ||||
| 			msg = "Certificate not issued by this issuer" | ||||
| 		case InvalidStatus: | ||||
| 			msg = "Invalid revocation status" | ||||
| 		} | ||||
| 	case CertificateError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Unknown certificate error" | ||||
| 		case ReadFailed: | ||||
| 			msg = "Failed to read certificate" | ||||
| 		case DecodeFailed: | ||||
| 			msg = "Failed to decode certificate" | ||||
| 		case ParseFailed: | ||||
| 			msg = "Failed to parse certificate" | ||||
| 		case SelfSigned: | ||||
| 			msg = "Certificate is self signed" | ||||
| 		case VerifyFailed: | ||||
| 			msg = "Unable to verify certificate" | ||||
| 		case BadRequest: | ||||
| 			msg = "Invalid certificate request" | ||||
| 		case MissingSerial: | ||||
| 			msg = "Missing serial number in request" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category CertificateError.", | ||||
| 				reason)) | ||||
|  | ||||
| 		} | ||||
| 	case PrivateKeyError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Unknown private key error" | ||||
| 		case ReadFailed: | ||||
| 			msg = "Failed to read private key" | ||||
| 		case DecodeFailed: | ||||
| 			msg = "Failed to decode private key" | ||||
| 		case ParseFailed: | ||||
| 			msg = "Failed to parse private key" | ||||
| 		case Encrypted: | ||||
| 			msg = "Private key is encrypted." | ||||
| 		case NotRSAOrECC: | ||||
| 			msg = "Private key algorithm is not RSA or ECC" | ||||
| 		case KeyMismatch: | ||||
| 			msg = "Private key does not match public key" | ||||
| 		case GenerationFailed: | ||||
| 			msg = "Failed to new private key" | ||||
| 		case Unavailable: | ||||
| 			msg = "Private key is unavailable" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PrivateKeyError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case IntermediatesError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Unknown intermediate certificate error" | ||||
| 		case ReadFailed: | ||||
| 			msg = "Failed to read intermediate certificate" | ||||
| 		case DecodeFailed: | ||||
| 			msg = "Failed to decode intermediate certificate" | ||||
| 		case ParseFailed: | ||||
| 			msg = "Failed to parse intermediate certificate" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category IntermediatesError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case RootError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Unknown root certificate error" | ||||
| 		case ReadFailed: | ||||
| 			msg = "Failed to read root certificate" | ||||
| 		case DecodeFailed: | ||||
| 			msg = "Failed to decode root certificate" | ||||
| 		case ParseFailed: | ||||
| 			msg = "Failed to parse root certificate" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category RootError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case PolicyError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Unknown policy error" | ||||
| 		case NoKeyUsages: | ||||
| 			msg = "Invalid policy: no key usage available" | ||||
| 		case InvalidPolicy: | ||||
| 			msg = "Invalid or unknown policy" | ||||
| 		case InvalidRequest: | ||||
| 			msg = "Policy violation request" | ||||
| 		case UnknownProfile: | ||||
| 			msg = "Unknown policy profile" | ||||
| 		case UnmatchedWhitelist: | ||||
| 			msg = "Request does not match policy whitelist" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case DialError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Failed to dial remote server" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category DialError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case APIClientError: | ||||
| 		switch reason { | ||||
| 		case AuthenticationFailure: | ||||
| 			msg = "API client authentication failure" | ||||
| 		case JSONError: | ||||
| 			msg = "API client JSON config error" | ||||
| 		case ClientHTTPError: | ||||
| 			msg = "API client HTTP error" | ||||
| 		case IOError: | ||||
| 			msg = "API client IO error" | ||||
| 		case ServerRequestFailed: | ||||
| 			msg = "API client error: Server request failed" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category APIClientError.", | ||||
| 				reason)) | ||||
| 		} | ||||
| 	case CSRError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "CSR parsing failed due to unknown error" | ||||
| 		case ReadFailed: | ||||
| 			msg = "CSR file read failed" | ||||
| 		case ParseFailed: | ||||
| 			msg = "CSR Parsing failed" | ||||
| 		case DecodeFailed: | ||||
| 			msg = "CSR Decode failed" | ||||
| 		case BadRequest: | ||||
| 			msg = "CSR Bad request" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", reason)) | ||||
| 		} | ||||
| 	case CTError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Certificate transparency parsing failed due to unknown error" | ||||
| 		case PrecertSubmissionFailed: | ||||
| 			msg = "Certificate transparency precertificate submission failed" | ||||
| 		case PrecertMissingPoison: | ||||
| 			msg = "Precertificate is missing CT poison extension" | ||||
| 		case PrecertInvalidPoison: | ||||
| 			msg = "Precertificate contains an invalid CT poison extension" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CTError.", reason)) | ||||
| 		} | ||||
| 	case CertStoreError: | ||||
| 		switch reason { | ||||
| 		case Unknown: | ||||
| 			msg = "Certificate store action failed due to unknown error" | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CertStoreError.", reason)) | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.", | ||||
| 			category)) | ||||
| 	} | ||||
| 	return &Error{ErrorCode: errorCode, Message: msg} | ||||
| } | ||||
|  | ||||
| // Wrap returns an error that contains the given error and an error code derived from | ||||
| // the given category, reason and the error. Currently, to avoid confusion, it is not | ||||
| // allowed to create an error of category Success | ||||
| func Wrap(category Category, reason Reason, err error) *Error { | ||||
| 	errorCode := int(category) + int(reason) | ||||
| 	if err == nil { | ||||
| 		panic("Wrap needs a supplied error to initialize.") | ||||
| 	} | ||||
|  | ||||
| 	// do not double wrap a error | ||||
| 	switch err.(type) { | ||||
| 	case *Error: | ||||
| 		panic("Unable to wrap a wrapped error.") | ||||
| 	} | ||||
|  | ||||
| 	switch category { | ||||
| 	case CertificateError: | ||||
| 		// given VerifyFailed , report the status with more detailed status code | ||||
| 		// for some certificate errors we care. | ||||
| 		if reason == VerifyFailed { | ||||
| 			switch errorType := err.(type) { | ||||
| 			case x509.CertificateInvalidError: | ||||
| 				errorCode += certificateInvalid + int(errorType.Reason) | ||||
| 			case x509.UnknownAuthorityError: | ||||
| 				errorCode += unknownAuthority | ||||
| 			} | ||||
| 		} | ||||
| 	case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError, | ||||
| 		APIClientError, CSRError, CTError, CertStoreError, OCSPError: | ||||
| 	// no-op, just use the error | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.", | ||||
| 			category)) | ||||
| 	} | ||||
|  | ||||
| 	return &Error{ErrorCode: errorCode, Message: err.Error()} | ||||
|  | ||||
| } | ||||
							
								
								
									
										338
									
								
								vendor/github.com/cloudflare/cfssl/errors/error_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								vendor/github.com/cloudflare/cfssl/errors/error_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,338 @@ | ||||
| package errors | ||||
|  | ||||
| import ( | ||||
| 	"crypto/x509" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestNew(t *testing.T) { | ||||
| 	err := New(CertificateError, Unknown) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Error creation failed.") | ||||
| 	} | ||||
| 	if err.ErrorCode != int(CertificateError)+int(Unknown) { | ||||
| 		t.Fatal("Error code construction failed.") | ||||
| 	} | ||||
| 	if err.Message != "Unknown certificate error" { | ||||
| 		t.Fatal("Error message construction failed.") | ||||
| 	} | ||||
|  | ||||
| 	code := New(OCSPError, ReadFailed).ErrorCode | ||||
| 	if code != 8001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(OCSPError, IssuerMismatch).ErrorCode | ||||
| 	if code != 8100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(OCSPError, InvalidStatus).ErrorCode | ||||
| 	if code != 8200 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(CertificateError, Unknown).ErrorCode | ||||
| 	if code != 1000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, ReadFailed).ErrorCode | ||||
| 	if code != 1001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, DecodeFailed).ErrorCode | ||||
| 	if code != 1002 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, ParseFailed).ErrorCode | ||||
| 	if code != 1003 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, SelfSigned).ErrorCode | ||||
| 	if code != 1100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, VerifyFailed).ErrorCode | ||||
| 	if code != 1200 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, BadRequest).ErrorCode | ||||
| 	if code != 1300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CertificateError, MissingSerial).ErrorCode | ||||
| 	if code != 1400 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(PrivateKeyError, Unknown).ErrorCode | ||||
| 	if code != 2000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, ReadFailed).ErrorCode | ||||
| 	if code != 2001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, DecodeFailed).ErrorCode | ||||
| 	if code != 2002 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, ParseFailed).ErrorCode | ||||
| 	if code != 2003 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, Encrypted).ErrorCode | ||||
| 	if code != 2100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, NotRSAOrECC).ErrorCode | ||||
| 	if code != 2200 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, KeyMismatch).ErrorCode | ||||
| 	if code != 2300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, GenerationFailed).ErrorCode | ||||
| 	if code != 2400 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PrivateKeyError, Unavailable).ErrorCode | ||||
| 	if code != 2500 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(IntermediatesError, Unknown).ErrorCode | ||||
| 	if code != 3000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(IntermediatesError, ReadFailed).ErrorCode | ||||
| 	if code != 3001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(IntermediatesError, DecodeFailed).ErrorCode | ||||
| 	if code != 3002 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(IntermediatesError, ParseFailed).ErrorCode | ||||
| 	if code != 3003 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(RootError, Unknown).ErrorCode | ||||
| 	if code != 4000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(RootError, ReadFailed).ErrorCode | ||||
| 	if code != 4001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(RootError, DecodeFailed).ErrorCode | ||||
| 	if code != 4002 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(RootError, ParseFailed).ErrorCode | ||||
| 	if code != 4003 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(PolicyError, Unknown).ErrorCode | ||||
| 	if code != 5000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PolicyError, NoKeyUsages).ErrorCode | ||||
| 	if code != 5100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PolicyError, InvalidPolicy).ErrorCode | ||||
| 	if code != 5200 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PolicyError, InvalidRequest).ErrorCode | ||||
| 	if code != 5300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(PolicyError, UnknownProfile).ErrorCode | ||||
| 	if code != 5400 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(DialError, Unknown).ErrorCode | ||||
| 	if code != 6000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(APIClientError, AuthenticationFailure).ErrorCode | ||||
| 	if code != 7100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(APIClientError, JSONError).ErrorCode | ||||
| 	if code != 7200 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(APIClientError, ClientHTTPError).ErrorCode | ||||
| 	if code != 7400 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(APIClientError, IOError).ErrorCode | ||||
| 	if code != 7300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(APIClientError, ServerRequestFailed).ErrorCode | ||||
| 	if code != 7500 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(CSRError, Unknown).ErrorCode | ||||
| 	if code != 9000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CSRError, ReadFailed).ErrorCode | ||||
| 	if code != 9001 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CSRError, DecodeFailed).ErrorCode | ||||
| 	if code != 9002 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CSRError, ParseFailed).ErrorCode | ||||
| 	if code != 9003 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CSRError, KeyMismatch).ErrorCode | ||||
| 	if code != 9300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CSRError, BadRequest).ErrorCode | ||||
| 	if code != 9300 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
|  | ||||
| 	code = New(CTError, Unknown).ErrorCode | ||||
| 	if code != 10000 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| 	code = New(CTError, PrecertSubmissionFailed).ErrorCode | ||||
| 	if code != 10100 { | ||||
| 		t.Fatal("Improper error code") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestWrap(t *testing.T) { | ||||
| 	msg := "Arbitrary error message" | ||||
| 	err := Wrap(CertificateError, Unknown, errors.New(msg)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Error creation failed.") | ||||
| 	} | ||||
| 	if err.ErrorCode != int(CertificateError)+int(Unknown) { | ||||
| 		t.Fatal("Error code construction failed.") | ||||
| 	} | ||||
| 	if err.Message != msg { | ||||
| 		t.Fatal("Error message construction failed.") | ||||
| 	} | ||||
|  | ||||
| 	err = Wrap(CertificateError, VerifyFailed, x509.CertificateInvalidError{Reason: x509.Expired}) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Error creation failed.") | ||||
| 	} | ||||
| 	if err.ErrorCode != int(CertificateError)+int(VerifyFailed)+certificateInvalid+int(x509.Expired) { | ||||
| 		t.Fatal("Error code construction failed.") | ||||
| 	} | ||||
| 	if err.Message != "x509: certificate has expired or is not yet valid" { | ||||
| 		t.Fatal("Error message construction failed.") | ||||
| 	} | ||||
|  | ||||
| 	err = Wrap(CertificateError, VerifyFailed, x509.UnknownAuthorityError{}) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Error creation failed.") | ||||
| 	} | ||||
|  | ||||
| 	err = Wrap(RootError, Unknown, errors.New(msg)) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Error creation failed.") | ||||
| 	} | ||||
| 	if err.ErrorCode != int(RootError)+int(Unknown) { | ||||
| 		t.Fatal("Error code construction failed.") | ||||
| 	} | ||||
| 	if err.Message != msg { | ||||
| 		t.Fatal("Error message construction failed.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMarshal(t *testing.T) { | ||||
| 	msg := "Arbitrary error message" | ||||
| 	err := Wrap(CertificateError, Unknown, errors.New(msg)) | ||||
| 	bytes, _ := json.Marshal(err) | ||||
| 	var received Error | ||||
| 	json.Unmarshal(bytes, &received) | ||||
| 	if received.ErrorCode != int(CertificateError)+int(Unknown) { | ||||
| 		t.Fatal("Error code construction failed.") | ||||
| 	} | ||||
| 	if received.Message != msg { | ||||
| 		t.Fatal("Error message construction failed.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestErrorString(t *testing.T) { | ||||
| 	msg := "Arbitrary error message" | ||||
| 	err := Wrap(CertificateError, Unknown, errors.New(msg)) | ||||
| 	str := err.Error() | ||||
| 	if str != `{"code":1000,"message":"`+msg+`"}` { | ||||
| 		t.Fatal("Incorrect Error():", str) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestHTTP(t *testing.T) { | ||||
| 	err := NewMethodNotAllowed("GET") | ||||
| 	if err == nil { | ||||
| 		t.Fatal("New Mathod Check failed") | ||||
| 	} | ||||
|  | ||||
| 	err = NewBadRequest(errors.New("Bad Request")) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("New Bad Request Check failed") | ||||
| 	} | ||||
|  | ||||
| 	if err.StatusCode != 400 { | ||||
| 		t.Fatal("New Bad Request error code construction failed") | ||||
| 	} | ||||
|  | ||||
| 	err = NewBadRequestString("Bad Request String") | ||||
| 	if err == nil { | ||||
| 		t.Fatal("New Bad Request String Check failed") | ||||
| 	} | ||||
|  | ||||
| 	if err.StatusCode != 400 { | ||||
| 		t.Fatal("New Bad Request String error code construction failed") | ||||
| 	} | ||||
|  | ||||
| 	err = NewBadRequestMissingParameter("Request Missing Parameter") | ||||
| 	if err == nil { | ||||
| 		t.Fatal("New Bad Request Missing Parameter Check failed") | ||||
| 	} | ||||
|  | ||||
| 	if err.StatusCode != 400 { | ||||
| 		t.Fatal("New Bad Request Missing Parameter error code construction failed") | ||||
| 	} | ||||
|  | ||||
| 	err = NewBadRequestUnwantedParameter("Unwanted Parameter Present In Request") | ||||
| 	if err == nil { | ||||
| 		t.Fatal("New Bad Request Unwanted Parameter Check failed") | ||||
| 	} | ||||
|  | ||||
| 	if err.StatusCode != 400 { | ||||
| 		t.Fatal("New Bad Request Unwanted Parameter error code construction failed") | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestHTTPErrorString(t *testing.T) { | ||||
| 	method := "GET" | ||||
| 	err := NewMethodNotAllowed(method) | ||||
| 	str := err.Error() | ||||
| 	if str != `Method is not allowed:"`+method+`"` { | ||||
| 		t.Fatal("Incorrect Error():", str) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										47
									
								
								vendor/github.com/cloudflare/cfssl/errors/http.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/cloudflare/cfssl/errors/http.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| package errors | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| // HTTPError is an augmented error with a HTTP status code. | ||||
| type HTTPError struct { | ||||
| 	StatusCode int | ||||
| 	error | ||||
| } | ||||
|  | ||||
| // Error implements the error interface. | ||||
| func (e *HTTPError) Error() string { | ||||
| 	return e.error.Error() | ||||
| } | ||||
|  | ||||
| // NewMethodNotAllowed returns an appropriate error in the case that | ||||
| // an HTTP client uses an invalid method (i.e. a GET in place of a POST) | ||||
| // on an API endpoint. | ||||
| func NewMethodNotAllowed(method string) *HTTPError { | ||||
| 	return &HTTPError{http.StatusMethodNotAllowed, errors.New(`Method is not allowed:"` + method + `"`)} | ||||
| } | ||||
|  | ||||
| // NewBadRequest creates a HttpError with the given error and error code 400. | ||||
| func NewBadRequest(err error) *HTTPError { | ||||
| 	return &HTTPError{http.StatusBadRequest, err} | ||||
| } | ||||
|  | ||||
| // NewBadRequestString returns a HttpError with the supplied message | ||||
| // and error code 400. | ||||
| func NewBadRequestString(s string) *HTTPError { | ||||
| 	return NewBadRequest(errors.New(s)) | ||||
| } | ||||
|  | ||||
| // NewBadRequestMissingParameter returns a 400 HttpError as a required | ||||
| // parameter is missing in the HTTP request. | ||||
| func NewBadRequestMissingParameter(s string) *HTTPError { | ||||
| 	return NewBadRequestString(`Missing parameter "` + s + `"`) | ||||
| } | ||||
|  | ||||
| // NewBadRequestUnwantedParameter returns a 400 HttpError as a unnecessary | ||||
| // parameter is present in the HTTP request. | ||||
| func NewBadRequestUnwantedParameter(s string) *HTTPError { | ||||
| 	return NewBadRequestString(`Unwanted parameter "` + s + `"`) | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| // Package derhelpers implements common functionality | ||||
| // on DER encoded data | ||||
| package derhelpers | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
|  | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| ) | ||||
|  | ||||
| // ParsePrivateKeyDER parses a PKCS #1, PKCS #8, or elliptic curve | ||||
| // DER-encoded private key. The key must not be in PEM format. | ||||
| func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { | ||||
| 	generalKey, err := x509.ParsePKCS8PrivateKey(keyDER) | ||||
| 	if err != nil { | ||||
| 		generalKey, err = x509.ParsePKCS1PrivateKey(keyDER) | ||||
| 		if err != nil { | ||||
| 			generalKey, err = x509.ParseECPrivateKey(keyDER) | ||||
| 			if err != nil { | ||||
| 				// We don't include the actual error into | ||||
| 				// the final error. The reason might be | ||||
| 				// we don't want to leak any info about | ||||
| 				// the private key. | ||||
| 				return nil, cferr.New(cferr.PrivateKeyError, | ||||
| 					cferr.ParseFailed) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	switch generalKey.(type) { | ||||
| 	case *rsa.PrivateKey: | ||||
| 		return generalKey.(*rsa.PrivateKey), nil | ||||
| 	case *ecdsa.PrivateKey: | ||||
| 		return generalKey.(*ecdsa.PrivateKey), nil | ||||
| 	} | ||||
|  | ||||
| 	// should never reach here | ||||
| 	return nil, cferr.New(cferr.PrivateKeyError, cferr.ParseFailed) | ||||
| } | ||||
							
								
								
									
										577
									
								
								vendor/github.com/cloudflare/cfssl/helpers/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										577
									
								
								vendor/github.com/cloudflare/cfssl/helpers/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,577 @@ | ||||
| // Package helpers implements utility functionality common to many | ||||
| // CFSSL packages. | ||||
| package helpers | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/google/certificate-transparency-go" | ||||
| 	cttls "github.com/google/certificate-transparency-go/tls" | ||||
| 	ctx509 "github.com/google/certificate-transparency-go/x509" | ||||
| 	"golang.org/x/crypto/ocsp" | ||||
|  | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/crypto/pkcs7" | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers/derhelpers" | ||||
| 	"github.com/cloudflare/cfssl/log" | ||||
| 	"golang.org/x/crypto/pkcs12" | ||||
| ) | ||||
|  | ||||
| // OneYear is a time.Duration representing a year's worth of seconds. | ||||
| const OneYear = 8760 * time.Hour | ||||
|  | ||||
| // OneDay is a time.Duration representing a day's worth of seconds. | ||||
| const OneDay = 24 * time.Hour | ||||
|  | ||||
| // InclusiveDate returns the time.Time representation of a date - 1 | ||||
| // nanosecond. This allows time.After to be used inclusively. | ||||
| func InclusiveDate(year int, month time.Month, day int) time.Time { | ||||
| 	return time.Date(year, month, day, 0, 0, 0, 0, time.UTC).Add(-1 * time.Nanosecond) | ||||
| } | ||||
|  | ||||
| // Jul2012 is the July 2012 CAB Forum deadline for when CAs must stop | ||||
| // issuing certificates valid for more than 5 years. | ||||
| var Jul2012 = InclusiveDate(2012, time.July, 01) | ||||
|  | ||||
| // Apr2015 is the April 2015 CAB Forum deadline for when CAs must stop | ||||
| // issuing certificates valid for more than 39 months. | ||||
| var Apr2015 = InclusiveDate(2015, time.April, 01) | ||||
|  | ||||
| // KeyLength returns the bit size of ECDSA or RSA PublicKey | ||||
| func KeyLength(key interface{}) int { | ||||
| 	if key == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	if ecdsaKey, ok := key.(*ecdsa.PublicKey); ok { | ||||
| 		return ecdsaKey.Curve.Params().BitSize | ||||
| 	} else if rsaKey, ok := key.(*rsa.PublicKey); ok { | ||||
| 		return rsaKey.N.BitLen() | ||||
| 	} | ||||
|  | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| // ExpiryTime returns the time when the certificate chain is expired. | ||||
| func ExpiryTime(chain []*x509.Certificate) (notAfter time.Time) { | ||||
| 	if len(chain) == 0 { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	notAfter = chain[0].NotAfter | ||||
| 	for _, cert := range chain { | ||||
| 		if notAfter.After(cert.NotAfter) { | ||||
| 			notAfter = cert.NotAfter | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MonthsValid returns the number of months for which a certificate is valid. | ||||
| func MonthsValid(c *x509.Certificate) int { | ||||
| 	issued := c.NotBefore | ||||
| 	expiry := c.NotAfter | ||||
| 	years := (expiry.Year() - issued.Year()) | ||||
| 	months := years*12 + int(expiry.Month()) - int(issued.Month()) | ||||
|  | ||||
| 	// Round up if valid for less than a full month | ||||
| 	if expiry.Day() > issued.Day() { | ||||
| 		months++ | ||||
| 	} | ||||
| 	return months | ||||
| } | ||||
|  | ||||
| // ValidExpiry determines if a certificate is valid for an acceptable | ||||
| // length of time per the CA/Browser Forum baseline requirements. | ||||
| // See https://cabforum.org/wp-content/uploads/CAB-Forum-BR-1.3.0.pdf | ||||
| func ValidExpiry(c *x509.Certificate) bool { | ||||
| 	issued := c.NotBefore | ||||
|  | ||||
| 	var maxMonths int | ||||
| 	switch { | ||||
| 	case issued.After(Apr2015): | ||||
| 		maxMonths = 39 | ||||
| 	case issued.After(Jul2012): | ||||
| 		maxMonths = 60 | ||||
| 	case issued.Before(Jul2012): | ||||
| 		maxMonths = 120 | ||||
| 	} | ||||
|  | ||||
| 	if MonthsValid(c) > maxMonths { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // SignatureString returns the TLS signature string corresponding to | ||||
| // an X509 signature algorithm. | ||||
| func SignatureString(alg x509.SignatureAlgorithm) string { | ||||
| 	switch alg { | ||||
| 	case x509.MD2WithRSA: | ||||
| 		return "MD2WithRSA" | ||||
| 	case x509.MD5WithRSA: | ||||
| 		return "MD5WithRSA" | ||||
| 	case x509.SHA1WithRSA: | ||||
| 		return "SHA1WithRSA" | ||||
| 	case x509.SHA256WithRSA: | ||||
| 		return "SHA256WithRSA" | ||||
| 	case x509.SHA384WithRSA: | ||||
| 		return "SHA384WithRSA" | ||||
| 	case x509.SHA512WithRSA: | ||||
| 		return "SHA512WithRSA" | ||||
| 	case x509.DSAWithSHA1: | ||||
| 		return "DSAWithSHA1" | ||||
| 	case x509.DSAWithSHA256: | ||||
| 		return "DSAWithSHA256" | ||||
| 	case x509.ECDSAWithSHA1: | ||||
| 		return "ECDSAWithSHA1" | ||||
| 	case x509.ECDSAWithSHA256: | ||||
| 		return "ECDSAWithSHA256" | ||||
| 	case x509.ECDSAWithSHA384: | ||||
| 		return "ECDSAWithSHA384" | ||||
| 	case x509.ECDSAWithSHA512: | ||||
| 		return "ECDSAWithSHA512" | ||||
| 	default: | ||||
| 		return "Unknown Signature" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // HashAlgoString returns the hash algorithm name contains in the signature | ||||
| // method. | ||||
| func HashAlgoString(alg x509.SignatureAlgorithm) string { | ||||
| 	switch alg { | ||||
| 	case x509.MD2WithRSA: | ||||
| 		return "MD2" | ||||
| 	case x509.MD5WithRSA: | ||||
| 		return "MD5" | ||||
| 	case x509.SHA1WithRSA: | ||||
| 		return "SHA1" | ||||
| 	case x509.SHA256WithRSA: | ||||
| 		return "SHA256" | ||||
| 	case x509.SHA384WithRSA: | ||||
| 		return "SHA384" | ||||
| 	case x509.SHA512WithRSA: | ||||
| 		return "SHA512" | ||||
| 	case x509.DSAWithSHA1: | ||||
| 		return "SHA1" | ||||
| 	case x509.DSAWithSHA256: | ||||
| 		return "SHA256" | ||||
| 	case x509.ECDSAWithSHA1: | ||||
| 		return "SHA1" | ||||
| 	case x509.ECDSAWithSHA256: | ||||
| 		return "SHA256" | ||||
| 	case x509.ECDSAWithSHA384: | ||||
| 		return "SHA384" | ||||
| 	case x509.ECDSAWithSHA512: | ||||
| 		return "SHA512" | ||||
| 	default: | ||||
| 		return "Unknown Hash Algorithm" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // EncodeCertificatesPEM encodes a number of x509 certificates to PEM | ||||
| func EncodeCertificatesPEM(certs []*x509.Certificate) []byte { | ||||
| 	var buffer bytes.Buffer | ||||
| 	for _, cert := range certs { | ||||
| 		pem.Encode(&buffer, &pem.Block{ | ||||
| 			Type:  "CERTIFICATE", | ||||
| 			Bytes: cert.Raw, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return buffer.Bytes() | ||||
| } | ||||
|  | ||||
| // EncodeCertificatePEM encodes a single x509 certificates to PEM | ||||
| func EncodeCertificatePEM(cert *x509.Certificate) []byte { | ||||
| 	return EncodeCertificatesPEM([]*x509.Certificate{cert}) | ||||
| } | ||||
|  | ||||
| // ParseCertificatesPEM parses a sequence of PEM-encoded certificate and returns them, | ||||
| // can handle PEM encoded PKCS #7 structures. | ||||
| func ParseCertificatesPEM(certsPEM []byte) ([]*x509.Certificate, error) { | ||||
| 	var certs []*x509.Certificate | ||||
| 	var err error | ||||
| 	certsPEM = bytes.TrimSpace(certsPEM) | ||||
| 	for len(certsPEM) > 0 { | ||||
| 		var cert []*x509.Certificate | ||||
| 		cert, certsPEM, err = ParseOneCertificateFromPEM(certsPEM) | ||||
| 		if err != nil { | ||||
|  | ||||
| 			return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed) | ||||
| 		} else if cert == nil { | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		certs = append(certs, cert...) | ||||
| 	} | ||||
| 	if len(certsPEM) > 0 { | ||||
| 		return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) | ||||
| 	} | ||||
| 	return certs, nil | ||||
| } | ||||
|  | ||||
| // ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key, | ||||
| // either PKCS #7, PKCS #12, or raw x509. | ||||
| func ParseCertificatesDER(certsDER []byte, password string) (certs []*x509.Certificate, key crypto.Signer, err error) { | ||||
| 	certsDER = bytes.TrimSpace(certsDER) | ||||
| 	pkcs7data, err := pkcs7.ParsePKCS7(certsDER) | ||||
| 	if err != nil { | ||||
| 		var pkcs12data interface{} | ||||
| 		certs = make([]*x509.Certificate, 1) | ||||
| 		pkcs12data, certs[0], err = pkcs12.Decode(certsDER, password) | ||||
| 		if err != nil { | ||||
| 			certs, err = x509.ParseCertificates(certsDER) | ||||
| 			if err != nil { | ||||
| 				return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) | ||||
| 			} | ||||
| 		} else { | ||||
| 			key = pkcs12data.(crypto.Signer) | ||||
| 		} | ||||
| 	} else { | ||||
| 		if pkcs7data.ContentInfo != "SignedData" { | ||||
| 			return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info")) | ||||
| 		} | ||||
| 		certs = pkcs7data.Content.SignedData.Certificates | ||||
| 	} | ||||
| 	if certs == nil { | ||||
| 		return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed) | ||||
| 	} | ||||
| 	return certs, key, nil | ||||
| } | ||||
|  | ||||
| // ParseSelfSignedCertificatePEM parses a PEM-encoded certificate and check if it is self-signed. | ||||
| func ParseSelfSignedCertificatePEM(certPEM []byte) (*x509.Certificate, error) { | ||||
| 	cert, err := ParseCertificatePEM(certPEM) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.VerifyFailed, err) | ||||
| 	} | ||||
| 	return cert, nil | ||||
| } | ||||
|  | ||||
| // ParseCertificatePEM parses and returns a PEM-encoded certificate, | ||||
| // can handle PEM encoded PKCS #7 structures. | ||||
| func ParseCertificatePEM(certPEM []byte) (*x509.Certificate, error) { | ||||
| 	certPEM = bytes.TrimSpace(certPEM) | ||||
| 	cert, rest, err := ParseOneCertificateFromPEM(certPEM) | ||||
| 	if err != nil { | ||||
| 		// Log the actual parsing error but throw a default parse error message. | ||||
| 		log.Debugf("Certificate parsing error: %v", err) | ||||
| 		return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed) | ||||
| 	} else if cert == nil { | ||||
| 		return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) | ||||
| 	} else if len(rest) > 0 { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PEM file should contain only one object")) | ||||
| 	} else if len(cert) > 1 { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PKCS7 object in the PEM file should contain only one certificate")) | ||||
| 	} | ||||
| 	return cert[0], nil | ||||
| } | ||||
|  | ||||
| // ParseOneCertificateFromPEM attempts to parse one PEM encoded certificate object, | ||||
| // either a raw x509 certificate or a PKCS #7 structure possibly containing | ||||
| // multiple certificates, from the top of certsPEM, which itself may | ||||
| // contain multiple PEM encoded certificate objects. | ||||
| func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, error) { | ||||
|  | ||||
| 	block, rest := pem.Decode(certsPEM) | ||||
| 	if block == nil { | ||||
| 		return nil, rest, nil | ||||
| 	} | ||||
|  | ||||
| 	cert, err := x509.ParseCertificate(block.Bytes) | ||||
| 	if err != nil { | ||||
| 		pkcs7data, err := pkcs7.ParsePKCS7(block.Bytes) | ||||
| 		if err != nil { | ||||
| 			return nil, rest, err | ||||
| 		} | ||||
| 		if pkcs7data.ContentInfo != "SignedData" { | ||||
| 			return nil, rest, errors.New("only PKCS #7 Signed Data Content Info supported for certificate parsing") | ||||
| 		} | ||||
| 		certs := pkcs7data.Content.SignedData.Certificates | ||||
| 		if certs == nil { | ||||
| 			return nil, rest, errors.New("PKCS #7 structure contains no certificates") | ||||
| 		} | ||||
| 		return certs, rest, nil | ||||
| 	} | ||||
| 	var certs = []*x509.Certificate{cert} | ||||
| 	return certs, rest, nil | ||||
| } | ||||
|  | ||||
| // LoadPEMCertPool loads a pool of PEM certificates from file. | ||||
| func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) { | ||||
| 	if certsFile == "" { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	pemCerts, err := ioutil.ReadFile(certsFile) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return PEMToCertPool(pemCerts) | ||||
| } | ||||
|  | ||||
| // PEMToCertPool concerts PEM certificates to a CertPool. | ||||
| func PEMToCertPool(pemCerts []byte) (*x509.CertPool, error) { | ||||
| 	if len(pemCerts) == 0 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | ||||
| 	certPool := x509.NewCertPool() | ||||
| 	if !certPool.AppendCertsFromPEM(pemCerts) { | ||||
| 		return nil, errors.New("failed to load cert pool") | ||||
| 	} | ||||
|  | ||||
| 	return certPool, nil | ||||
| } | ||||
|  | ||||
| // ParsePrivateKeyPEM parses and returns a PEM-encoded private | ||||
| // key. The private key may be either an unencrypted PKCS#8, PKCS#1, | ||||
| // or elliptic private key. | ||||
| func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) { | ||||
| 	return ParsePrivateKeyPEMWithPassword(keyPEM, nil) | ||||
| } | ||||
|  | ||||
| // ParsePrivateKeyPEMWithPassword parses and returns a PEM-encoded private | ||||
| // key. The private key may be a potentially encrypted PKCS#8, PKCS#1, | ||||
| // or elliptic private key. | ||||
| func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.Signer, err error) { | ||||
| 	keyDER, err := GetKeyDERFromPEM(keyPEM, password) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return derhelpers.ParsePrivateKeyDER(keyDER) | ||||
| } | ||||
|  | ||||
| // GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes. | ||||
| func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) { | ||||
| 	keyDER, _ := pem.Decode(in) | ||||
| 	if keyDER != nil { | ||||
| 		if procType, ok := keyDER.Headers["Proc-Type"]; ok { | ||||
| 			if strings.Contains(procType, "ENCRYPTED") { | ||||
| 				if password != nil { | ||||
| 					return x509.DecryptPEMBlock(keyDER, password) | ||||
| 				} | ||||
| 				return nil, cferr.New(cferr.PrivateKeyError, cferr.Encrypted) | ||||
| 			} | ||||
| 		} | ||||
| 		return keyDER.Bytes, nil | ||||
| 	} | ||||
|  | ||||
| 	return nil, cferr.New(cferr.PrivateKeyError, cferr.DecodeFailed) | ||||
| } | ||||
|  | ||||
| // ParseCSR parses a PEM- or DER-encoded PKCS #10 certificate signing request. | ||||
| func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) { | ||||
| 	in = bytes.TrimSpace(in) | ||||
| 	p, rest := pem.Decode(in) | ||||
| 	if p != nil { | ||||
| 		if p.Type != "NEW CERTIFICATE REQUEST" && p.Type != "CERTIFICATE REQUEST" { | ||||
| 			return nil, rest, cferr.New(cferr.CSRError, cferr.BadRequest) | ||||
| 		} | ||||
|  | ||||
| 		csr, err = x509.ParseCertificateRequest(p.Bytes) | ||||
| 	} else { | ||||
| 		csr, err = x509.ParseCertificateRequest(in) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return nil, rest, err | ||||
| 	} | ||||
|  | ||||
| 	err = csr.CheckSignature() | ||||
| 	if err != nil { | ||||
| 		return nil, rest, err | ||||
| 	} | ||||
|  | ||||
| 	return csr, rest, nil | ||||
| } | ||||
|  | ||||
| // ParseCSRPEM parses a PEM-encoded certificate signing request. | ||||
| // It does not check the signature. This is useful for dumping data from a CSR | ||||
| // locally. | ||||
| func ParseCSRPEM(csrPEM []byte) (*x509.CertificateRequest, error) { | ||||
| 	block, _ := pem.Decode([]byte(csrPEM)) | ||||
| 	if block == nil { | ||||
| 		return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) | ||||
| 	} | ||||
| 	csrObject, err := x509.ParseCertificateRequest(block.Bytes) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return csrObject, nil | ||||
| } | ||||
|  | ||||
| // SignerAlgo returns an X.509 signature algorithm from a crypto.Signer. | ||||
| func SignerAlgo(priv crypto.Signer) x509.SignatureAlgorithm { | ||||
| 	switch pub := priv.Public().(type) { | ||||
| 	case *rsa.PublicKey: | ||||
| 		bitLength := pub.N.BitLen() | ||||
| 		switch { | ||||
| 		case bitLength >= 4096: | ||||
| 			return x509.SHA512WithRSA | ||||
| 		case bitLength >= 3072: | ||||
| 			return x509.SHA384WithRSA | ||||
| 		case bitLength >= 2048: | ||||
| 			return x509.SHA256WithRSA | ||||
| 		default: | ||||
| 			return x509.SHA1WithRSA | ||||
| 		} | ||||
| 	case *ecdsa.PublicKey: | ||||
| 		switch pub.Curve { | ||||
| 		case elliptic.P521(): | ||||
| 			return x509.ECDSAWithSHA512 | ||||
| 		case elliptic.P384(): | ||||
| 			return x509.ECDSAWithSHA384 | ||||
| 		case elliptic.P256(): | ||||
| 			return x509.ECDSAWithSHA256 | ||||
| 		default: | ||||
| 			return x509.ECDSAWithSHA1 | ||||
| 		} | ||||
| 	default: | ||||
| 		return x509.UnknownSignatureAlgorithm | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // LoadClientCertificate load key/certificate from pem files | ||||
| func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, error) { | ||||
| 	if certFile != "" && keyFile != "" { | ||||
| 		cert, err := tls.LoadX509KeyPair(certFile, keyFile) | ||||
| 		if err != nil { | ||||
| 			log.Critical("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile) | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		log.Debug("Client certificate loaded ") | ||||
| 		return &cert, nil | ||||
| 	} | ||||
| 	return nil, nil | ||||
| } | ||||
|  | ||||
| // CreateTLSConfig creates a tls.Config object from certs and roots | ||||
| func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Config { | ||||
| 	var certs []tls.Certificate | ||||
| 	if cert != nil { | ||||
| 		certs = []tls.Certificate{*cert} | ||||
| 	} | ||||
| 	return &tls.Config{ | ||||
| 		Certificates: certs, | ||||
| 		RootCAs:      remoteCAs, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SerializeSCTList serializes a list of SCTs. | ||||
| func SerializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) { | ||||
| 	list := ctx509.SignedCertificateTimestampList{} | ||||
| 	for _, sct := range sctList { | ||||
| 		sctBytes, err := cttls.Marshal(sct) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		list.SCTList = append(list.SCTList, ctx509.SerializedSCT{Val: sctBytes}) | ||||
| 	} | ||||
| 	return cttls.Marshal(list) | ||||
| } | ||||
|  | ||||
| // DeserializeSCTList deserializes a list of SCTs. | ||||
| func DeserializeSCTList(serializedSCTList []byte) ([]ct.SignedCertificateTimestamp, error) { | ||||
| 	var sctList ctx509.SignedCertificateTimestampList | ||||
| 	rest, err := cttls.Unmarshal(serializedSCTList, &sctList) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if len(rest) != 0 { | ||||
| 		return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT list contained trailing garbage")) | ||||
| 	} | ||||
| 	list := make([]ct.SignedCertificateTimestamp, len(sctList.SCTList)) | ||||
| 	for i, serializedSCT := range sctList.SCTList { | ||||
| 		var sct ct.SignedCertificateTimestamp | ||||
| 		rest, err := cttls.Unmarshal(serializedSCT.Val, &sct) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if len(rest) != 0 { | ||||
| 			return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT contained trailing garbage")) | ||||
| 		} | ||||
| 		list[i] = sct | ||||
| 	} | ||||
| 	return list, nil | ||||
| } | ||||
|  | ||||
| // SCTListFromOCSPResponse extracts the SCTList from an ocsp.Response, | ||||
| // returning an empty list if the SCT extension was not found or could not be | ||||
| // unmarshalled. | ||||
| func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTimestamp, error) { | ||||
| 	// This loop finds the SCTListExtension in the OCSP response. | ||||
| 	var SCTListExtension, ext pkix.Extension | ||||
| 	for _, ext = range response.Extensions { | ||||
| 		// sctExtOid is the ObjectIdentifier of a Signed Certificate Timestamp. | ||||
| 		sctExtOid := asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5} | ||||
| 		if ext.Id.Equal(sctExtOid) { | ||||
| 			SCTListExtension = ext | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// This code block extracts the sctList from the SCT extension. | ||||
| 	var sctList []ct.SignedCertificateTimestamp | ||||
| 	var err error | ||||
| 	if numBytes := len(SCTListExtension.Value); numBytes != 0 { | ||||
| 		var serializedSCTList []byte | ||||
| 		rest := make([]byte, numBytes) | ||||
| 		copy(rest, SCTListExtension.Value) | ||||
| 		for len(rest) != 0 { | ||||
| 			rest, err = asn1.Unmarshal(rest, &serializedSCTList) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) | ||||
| 			} | ||||
| 		} | ||||
| 		sctList, err = DeserializeSCTList(serializedSCTList) | ||||
| 	} | ||||
| 	return sctList, err | ||||
| } | ||||
|  | ||||
| // ReadBytes reads a []byte either from a file or an environment variable. | ||||
| // If valFile has a prefix of 'env:', the []byte is read from the environment | ||||
| // using the subsequent name. If the prefix is 'file:' the []byte is read from | ||||
| // the subsequent file. If no prefix is provided, valFile is assumed to be a | ||||
| // file path. | ||||
| func ReadBytes(valFile string) ([]byte, error) { | ||||
| 	switch splitVal := strings.SplitN(valFile, ":", 2); len(splitVal) { | ||||
| 	case 1: | ||||
| 		return ioutil.ReadFile(valFile) | ||||
| 	case 2: | ||||
| 		switch splitVal[0] { | ||||
| 		case "env": | ||||
| 			return []byte(os.Getenv(splitVal[1])), nil | ||||
| 		case "file": | ||||
| 			return ioutil.ReadFile(splitVal[1]) | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("unknown prefix: %s", splitVal[0]) | ||||
| 		} | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("multiple prefixes: %s", | ||||
| 			strings.Join(splitVal[:len(splitVal)-1], ", ")) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										629
									
								
								vendor/github.com/cloudflare/cfssl/helpers/helpers_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										629
									
								
								vendor/github.com/cloudflare/cfssl/helpers/helpers_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,629 @@ | ||||
| package helpers | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/pem" | ||||
| 	"io/ioutil" | ||||
| 	"math" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"golang.org/x/crypto/ocsp" | ||||
|  | ||||
| 	"github.com/google/certificate-transparency-go" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	testCertFile                 = "testdata/cert.pem" | ||||
| 	testCertDERFile              = "testdata/cert.der" | ||||
| 	testBundleFile               = "testdata/bundle.pem" | ||||
| 	testExtraWSCertFile          = "testdata/cert_with_whitespace.pem" | ||||
| 	testExtraWSBundleFile        = "testdata/bundle_with_whitespace.pem" | ||||
| 	testMessedUpBundleFile       = "testdata/messed_up_bundle.pem" | ||||
| 	testMessedUpCertFile         = "testdata/messedupcert.pem" | ||||
| 	testEmptyCertFile            = "testdata/emptycert.pem" | ||||
| 	testPrivateRSAKey            = "testdata/priv_rsa_key.pem" | ||||
| 	testPrivateECDSAKey          = "testdata/private_ecdsa_key.pem" | ||||
| 	testUnsupportedECDSAKey      = "testdata/secp256k1-key.pem" | ||||
| 	testMessedUpPrivateKey       = "testdata/messed_up_priv_key.pem" | ||||
| 	testEncryptedPrivateKey      = "testdata/enc_priv_key.pem" | ||||
| 	testEmptyPem                 = "testdata/empty.pem" | ||||
| 	testNoHeaderCert             = "testdata/noheadercert.pem" | ||||
| 	testSinglePKCS7              = "testdata/cert_pkcs7.pem"  // openssl crl2pkcs7 -nocrl -out cert_pkcs7.pem -in cert.pem | ||||
| 	testEmptyPKCS7DER            = "testdata/empty_pkcs7.der" // openssl crl2pkcs7 -nocrl -out empty_pkcs7.der -outform der | ||||
| 	testEmptyPKCS7PEM            = "testdata/empty_pkcs7.pem" // openssl crl2pkcs7 -nocrl -out empty_pkcs7.pem -outform pem | ||||
| 	testMultiplePKCS7            = "testdata/bundle_pkcs7.pem" | ||||
| 	testPKCS12EmptyPswd          = "testdata/emptypasswordpkcs12.p12" | ||||
| 	testPKCS12Passwordispassword = "testdata/passwordpkcs12.p12" | ||||
| 	testPKCS12MultipleCerts      = "testdata/multiplecerts.p12" | ||||
| 	testCSRPEM                   = "testdata/test.csr.pem" | ||||
| 	testCSRPEMBad                = "testdata/test.bad.csr.pem" | ||||
| ) | ||||
|  | ||||
| func TestParseCertificatesDER(t *testing.T) { | ||||
| 	var password = []string{"password", "", ""} | ||||
| 	for i, testFile := range []string{testPKCS12Passwordispassword, testPKCS12EmptyPswd, testCertDERFile} { | ||||
| 		testDER, err := ioutil.ReadFile(testFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 		if _, _, err := ParseCertificatesDER(testDER, password[i]); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 		// Incorrect Password for PKCS12 formatted files | ||||
| 		if _, _, err := ParseCertificatesDER(testDER, "incorrectpassword"); err == nil && i != 2 { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	testDER, err := ioutil.ReadFile(testEmptyPKCS7DER) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	// PKCS7 with no certificates | ||||
| 	if _, _, err := ParseCertificatesDER(testDER, ""); err == nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestKeyLength(t *testing.T) { | ||||
| 	expNil := 0 | ||||
| 	recNil := KeyLength(nil) | ||||
| 	if expNil != recNil { | ||||
| 		t.Fatal("KeyLength on nil did not return 0") | ||||
| 	} | ||||
|  | ||||
| 	expNonsense := 0 | ||||
| 	inNonsense := "string?" | ||||
| 	outNonsense := KeyLength(inNonsense) | ||||
| 	if expNonsense != outNonsense { | ||||
| 		t.Fatal("KeyLength malfunctioning on nonsense input") | ||||
| 	} | ||||
|  | ||||
| 	//test the ecdsa branch | ||||
| 	ecdsaPriv, _ := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) | ||||
| 	ecdsaIn, _ := ecdsaPriv.Public().(*ecdsa.PublicKey) | ||||
| 	expEcdsa := ecdsaIn.Curve.Params().BitSize | ||||
| 	outEcdsa := KeyLength(ecdsaIn) | ||||
| 	if expEcdsa != outEcdsa { | ||||
| 		t.Fatal("KeyLength malfunctioning on ecdsa input") | ||||
| 	} | ||||
|  | ||||
| 	//test the rsa branch | ||||
| 	rsaPriv, _ := rsa.GenerateKey(rand.Reader, 256) | ||||
| 	rsaIn, _ := rsaPriv.Public().(*rsa.PublicKey) | ||||
| 	expRsa := rsaIn.N.BitLen() | ||||
| 	outRsa := KeyLength(rsaIn) | ||||
|  | ||||
| 	if expRsa != outRsa { | ||||
| 		t.Fatal("KeyLength malfunctioning on rsa input") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestExpiryTime(t *testing.T) { | ||||
| 	// nil case | ||||
| 	var expNil time.Time | ||||
| 	inNil := []*x509.Certificate{} | ||||
| 	outNil := ExpiryTime(inNil) | ||||
| 	if expNil != outNil { | ||||
| 		t.Fatal("Expiry time is malfunctioning on empty input") | ||||
| 	} | ||||
|  | ||||
| 	//read a pem file and use that expiry date | ||||
| 	bytes, _ := ioutil.ReadFile(testBundleFile) | ||||
| 	certs, err := ParseCertificatesPEM(bytes) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 	expected := time.Date(2014, time.April, 15, 0, 0, 0, 0, time.UTC) | ||||
| 	out := ExpiryTime(certs) | ||||
| 	if out != expected { | ||||
| 		t.Fatalf("Expected %v, got %v", expected, out) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMonthsValid(t *testing.T) { | ||||
| 	var cert = &x509.Certificate{ | ||||
| 		NotBefore: time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC), | ||||
| 		NotAfter:  time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC), | ||||
| 	} | ||||
|  | ||||
| 	if MonthsValid(cert) != 0 { | ||||
| 		t.Fail() | ||||
| 	} | ||||
|  | ||||
| 	cert.NotAfter = time.Date(2016, time.April, 01, 0, 0, 0, 0, time.UTC) | ||||
| 	if MonthsValid(cert) != 12 { | ||||
| 		t.Fail() | ||||
| 	} | ||||
|  | ||||
| 	// extra days should be rounded up to 1 month | ||||
| 	cert.NotAfter = time.Date(2016, time.April, 02, 0, 0, 0, 0, time.UTC) | ||||
| 	if MonthsValid(cert) != 13 { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestHasValidExpiry(t *testing.T) { | ||||
| 	// Issue period > April 1, 2015 | ||||
| 	var cert = &x509.Certificate{ | ||||
| 		NotBefore: time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC), | ||||
| 		NotAfter:  time.Date(2016, time.April, 01, 0, 0, 0, 0, time.UTC), | ||||
| 	} | ||||
|  | ||||
| 	if !ValidExpiry(cert) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
|  | ||||
| 	cert.NotAfter = time.Date(2019, time.April, 01, 01, 0, 0, 0, time.UTC) | ||||
| 	if ValidExpiry(cert) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
|  | ||||
| 	// Issue period < July 1, 2012 | ||||
| 	cert.NotBefore = time.Date(2009, time.March, 01, 0, 0, 0, 0, time.UTC) | ||||
| 	if ValidExpiry(cert) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
|  | ||||
| 	// Issue period July 1, 2012 - April 1, 2015 | ||||
| 	cert.NotBefore = time.Date(2012, time.July, 01, 0, 0, 0, 0, time.UTC) | ||||
| 	cert.NotAfter = time.Date(2017, time.July, 01, 0, 0, 0, 0, time.UTC) | ||||
| 	if !ValidExpiry(cert) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestHashAlgoString(t *testing.T) { | ||||
| 	if HashAlgoString(x509.MD2WithRSA) != "MD2" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.MD5WithRSA) != "MD5" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.SHA1WithRSA) != "SHA1" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.SHA256WithRSA) != "SHA256" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.SHA384WithRSA) != "SHA384" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.SHA512WithRSA) != "SHA512" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.DSAWithSHA1) != "SHA1" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.DSAWithSHA256) != "SHA256" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.ECDSAWithSHA1) != "SHA1" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.ECDSAWithSHA256) != "SHA256" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.ECDSAWithSHA384) != "SHA384" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(x509.ECDSAWithSHA512) != "SHA512" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| 	if HashAlgoString(math.MaxInt32) != "Unknown Hash Algorithm" { | ||||
| 		t.Fatal("standin") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSignatureString(t *testing.T) { | ||||
| 	if SignatureString(x509.MD2WithRSA) != "MD2WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.MD5WithRSA) != "MD5WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.SHA1WithRSA) != "SHA1WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.SHA256WithRSA) != "SHA256WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.SHA384WithRSA) != "SHA384WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.SHA512WithRSA) != "SHA512WithRSA" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.DSAWithSHA1) != "DSAWithSHA1" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.DSAWithSHA256) != "DSAWithSHA256" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.ECDSAWithSHA1) != "ECDSAWithSHA1" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.ECDSAWithSHA256) != "ECDSAWithSHA256" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.ECDSAWithSHA384) != "ECDSAWithSHA384" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(x509.ECDSAWithSHA512) != "ECDSAWithSHA512" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| 	if SignatureString(math.MaxInt32) != "Unknown Signature" { | ||||
| 		t.Fatal("Signature String functioning improperly") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestParseCertificatePEM(t *testing.T) { | ||||
| 	for _, testFile := range []string{testCertFile, testExtraWSCertFile, testSinglePKCS7} { | ||||
| 		certPEM, err := ioutil.ReadFile(testFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if _, err := ParseCertificatePEM(certPEM); err != nil { | ||||
| 			t.Log(testFile) | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| 	for _, testFile := range []string{testBundleFile, testMessedUpCertFile, testEmptyPKCS7PEM, testEmptyCertFile, testMultiplePKCS7} { | ||||
| 		certPEM, err := ioutil.ReadFile(testFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if _, err := ParseCertificatePEM(certPEM); err == nil { | ||||
| 			t.Fatal("Incorrect cert failed to raise error") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestParseCertificatesPEM(t *testing.T) { | ||||
| 	// expected cases | ||||
| 	for _, testFile := range []string{testBundleFile, testExtraWSBundleFile, testSinglePKCS7, testMultiplePKCS7} { | ||||
| 		bundlePEM, err := ioutil.ReadFile(testFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if _, err := ParseCertificatesPEM(bundlePEM); err != nil { | ||||
| 			t.Log(testFile) | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// test failure cases | ||||
| 	// few lines deleted, then headers removed | ||||
| 	for _, testFile := range []string{testMessedUpBundleFile, testEmptyPKCS7PEM, testNoHeaderCert} { | ||||
| 		bundlePEM, err := ioutil.ReadFile(testFile) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if _, err := ParseCertificatesPEM(bundlePEM); err == nil { | ||||
| 			t.Fatal("Incorrectly-formatted file failed to produce an error") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSelfSignedCertificatePEM(t *testing.T) { | ||||
| 	testPEM, _ := ioutil.ReadFile(testCertFile) | ||||
| 	_, err := ParseSelfSignedCertificatePEM(testPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	// a few lines deleted from the pem file | ||||
| 	wrongPEM, _ := ioutil.ReadFile(testMessedUpCertFile) | ||||
| 	_, err2 := ParseSelfSignedCertificatePEM(wrongPEM) | ||||
| 	if err2 == nil { | ||||
| 		t.Fatal("Improper pem file failed to raise an error") | ||||
| 	} | ||||
|  | ||||
| 	// alter the signature of a valid certificate | ||||
| 	blk, _ := pem.Decode(testPEM) | ||||
| 	blk.Bytes[len(blk.Bytes)-10]++ // some hacking to get to the sig | ||||
| 	alteredBytes := pem.EncodeToMemory(blk) | ||||
| 	_, err = ParseSelfSignedCertificatePEM(alteredBytes) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Incorrect cert failed to produce an error") | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestParsePrivateKeyPEM(t *testing.T) { | ||||
|  | ||||
| 	// expected cases | ||||
| 	testRSAPEM, _ := ioutil.ReadFile(testPrivateRSAKey) | ||||
| 	_, err := ParsePrivateKeyPEM(testRSAPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	testECDSAPEM, _ := ioutil.ReadFile(testPrivateECDSAKey) | ||||
| 	_, err = ParsePrivateKeyPEM(testECDSAPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// error cases | ||||
| 	errCases := []string{ | ||||
| 		testMessedUpPrivateKey,  // a few lines deleted | ||||
| 		testEmptyPem,            // empty file | ||||
| 		testEncryptedPrivateKey, // encrypted key | ||||
| 		testUnsupportedECDSAKey, // ECDSA curve not currently supported by Go standard library | ||||
| 	} | ||||
|  | ||||
| 	for _, fname := range errCases { | ||||
| 		testPEM, _ := ioutil.ReadFile(fname) | ||||
| 		_, err = ParsePrivateKeyPEM(testPEM) | ||||
| 		if err == nil { | ||||
| 			t.Fatal("Incorrect private key failed to produce an error") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| // Imported from signers/local/testdata/ | ||||
| const ecdsaTestCSR = "testdata/ecdsa256.csr" | ||||
|  | ||||
| func TestParseCSRPEM(t *testing.T) { | ||||
| 	in, err := ioutil.ReadFile(ecdsaTestCSR) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	_, _, err = ParseCSR(in) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	in[12]++ | ||||
| 	_, _, err = ParseCSR(in) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("Expected an invalid CSR.") | ||||
| 	} | ||||
| 	in[12]-- | ||||
| } | ||||
|  | ||||
| func TestParseCSRPEMMore(t *testing.T) { | ||||
| 	csrPEM, err := ioutil.ReadFile(testCSRPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if _, err := ParseCSRPEM(csrPEM); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	csrPEM, err = ioutil.ReadFile(testCSRPEMBad) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if _, err := ParseCSRPEM(csrPEM); err == nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if _, err := ParseCSRPEM([]byte("not even pem")); err == nil { | ||||
| 		t.Fatal("Expected an invalid CSR.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Imported from signers/local/testdata/ | ||||
| const rsaOldTestCSR = "testdata/rsa-old.csr" | ||||
|  | ||||
| func TestParseOldCSR(t *testing.T) { | ||||
| 	in, err := ioutil.ReadFile(rsaOldTestCSR) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
|  | ||||
| 	_, _, err = ParseCSR(in) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Imported from signers/local/testdata/ | ||||
| const clientCertFile = "testdata/ca.pem" | ||||
| const clientKeyFile = "testdata/ca_key.pem" | ||||
|  | ||||
| func TestClientCertParams(t *testing.T) { | ||||
| 	_, err := LoadClientCertificate(testCertFile, testPrivateRSAKey) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Unmatched cert/key should generate error") | ||||
| 	} | ||||
|  | ||||
| 	cert, err := LoadClientCertificate("", "") | ||||
| 	if err != nil || cert != nil { | ||||
| 		t.Fatal("Certificate atempted to loaded with missing key and cert") | ||||
| 	} | ||||
| 	cert, err = LoadClientCertificate(clientCertFile, "") | ||||
| 	if err != nil || cert != nil { | ||||
| 		t.Fatal("Certificate atempted to loaded with missing key") | ||||
| 	} | ||||
| 	cert, err = LoadClientCertificate("", clientKeyFile) | ||||
| 	if err != nil || cert != nil { | ||||
| 		t.Fatal("Certificate atempted to loaded with missing cert") | ||||
| 	} | ||||
|  | ||||
| 	cert, err = LoadClientCertificate(clientCertFile, clientKeyFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if cert == nil { | ||||
| 		t.Fatal("cert not created") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLoadPEMCertPool(t *testing.T) { | ||||
| 	certPool, err := PEMToCertPool([]byte{}) | ||||
| 	if certPool != nil || err != nil { | ||||
| 		t.Fatal("Empty file name should not generate error or a cert pool") | ||||
| 	} | ||||
|  | ||||
| 	in, err := ioutil.ReadFile(testEmptyPem) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 	certPool, err = PEMToCertPool(in) | ||||
| 	if certPool != nil { | ||||
| 		t.Fatal("Empty file should not generate a cert pool") | ||||
| 	} else if err == nil { | ||||
| 		t.Fatal("Expected error for empty file") | ||||
| 	} | ||||
|  | ||||
| 	in, err = ioutil.ReadFile(testEmptyCertFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 	certPool, err = PEMToCertPool(in) | ||||
| 	if certPool != nil { | ||||
| 		t.Fatal("Empty cert should not generate a cert pool") | ||||
| 	} else if err == nil { | ||||
| 		t.Fatal("Expected error for empty cert") | ||||
| 	} | ||||
|  | ||||
| 	in, err = ioutil.ReadFile(clientCertFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} | ||||
| 	certPool, err = PEMToCertPool(in) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%v", err) | ||||
| 	} else if certPool == nil { | ||||
| 		t.Fatal("cert pool not created") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // sctEquals returns true if all fields of both SCTs are equivalent. | ||||
| func sctEquals(sctA, sctB ct.SignedCertificateTimestamp) bool { | ||||
| 	if sctA.SCTVersion == sctB.SCTVersion && | ||||
| 		sctA.LogID == sctB.LogID && | ||||
| 		sctA.Timestamp == sctB.Timestamp && | ||||
| 		bytes.Equal(sctA.Extensions, sctB.Extensions) && | ||||
| 		sctA.Signature.Algorithm == sctB.Signature.Algorithm && | ||||
| 		bytes.Equal(sctA.Signature.Signature, sctA.Signature.Signature) { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // NOTE: TestDeserializeSCTList tests both DeserializeSCTList and | ||||
| // SerializeSCTList. | ||||
| func TestDeserializeSCTList(t *testing.T) { | ||||
| 	// Here we make sure that empty SCT lists return an error | ||||
| 	emptyLists := [][]byte{nil, {}} | ||||
| 	for _, emptyList := range emptyLists { | ||||
| 		_, err := DeserializeSCTList(emptyList) | ||||
| 		if err == nil { | ||||
| 			t.Fatalf("DeserializeSCTList(%v) should raise an error\n", emptyList) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Here we make sure that an SCT list with a zero SCT is deserialized | ||||
| 	// correctly | ||||
| 	var zeroSCT ct.SignedCertificateTimestamp | ||||
| 	serializedSCT, err := SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	deserializedSCTList, err := DeserializeSCTList(serializedSCT) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if !sctEquals(zeroSCT, (deserializedSCTList)[0]) { | ||||
| 		t.Fatal("SCTs don't match") | ||||
| 	} | ||||
|  | ||||
| 	// Here we verify that an error is raised when the SCT list length | ||||
| 	// field is greater than its actual length | ||||
| 	serializedSCT, err = SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	serializedSCT[0] = 15 | ||||
| 	_, err = DeserializeSCTList(serializedSCT) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("DeserializeSCTList should raise an error when " + | ||||
| 			"the SCT list length field and the list length don't match\n") | ||||
| 	} | ||||
|  | ||||
| 	// Here we verify that an error is raised when the SCT list length | ||||
| 	// field is less than its actual length | ||||
| 	serializedSCT[0] = 0 | ||||
| 	serializedSCT[1] = 0 | ||||
| 	_, err = DeserializeSCTList(serializedSCT) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("DeserializeSCTList should raise an error when " + | ||||
| 			"the SCT list length field and the list length don't match\n") | ||||
| 	} | ||||
|  | ||||
| 	// Here we verify that an error is raised when the SCT length field is | ||||
| 	// greater than its actual length | ||||
| 	serializedSCT[0] = 0 | ||||
| 	serializedSCT[1] = 49 | ||||
| 	serializedSCT[2] = 1 | ||||
| 	_, err = DeserializeSCTList(serializedSCT) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("DeserializeSCTList should raise an error when " + | ||||
| 			"the SCT length field and the SCT length don't match\n") | ||||
| 	} | ||||
|  | ||||
| 	// Here we verify that an error is raised when the SCT length field is | ||||
| 	// less than its actual length | ||||
| 	serializedSCT[2] = 0 | ||||
| 	serializedSCT[3] = 0 | ||||
| 	_, err = DeserializeSCTList(serializedSCT) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("DeserializeSCTList should raise an error when " + | ||||
| 			"the SCT length field and the SCT length don't match\n") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSCTListFromOCSPResponse(t *testing.T) { | ||||
| 	var response ocsp.Response | ||||
| 	lst, err := SCTListFromOCSPResponse(&response) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if len(lst) != 0 { | ||||
| 		t.Fatal("SCTListFromOCSPResponse should return an empty SCT list for an empty extension") | ||||
| 	} | ||||
|  | ||||
| 	var zeroSCT ct.SignedCertificateTimestamp | ||||
| 	serializedSCTList, err := SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("failed to serialize SCT list") | ||||
| 	} | ||||
| 	serializedSCTList, err = asn1.Marshal(serializedSCTList) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("failed to serialize SCT list") | ||||
| 	} | ||||
| 	// The value of Id below is the object identifier of the OCSP Stapling | ||||
| 	// SCT extension (see section 3.3. of RFC 6962). | ||||
| 	response.Extensions = []pkix.Extension{{ | ||||
| 		Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5}, | ||||
| 		Critical: false, | ||||
| 		Value:    serializedSCTList, | ||||
| 	}} | ||||
| 	lst, err = SCTListFromOCSPResponse(&response) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if !sctEquals(zeroSCT, lst[0]) { | ||||
| 		t.Fatal("SCTs don't match") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEczCCAl2gAwIBAgIIDARj8BWNsscwCwYJKoZIhvcNAQELMIGMMQswCQYDVQQG | ||||
| EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp | ||||
| bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv | ||||
| cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwMzAyMDAw | ||||
| MDAwWhcNMTkwNDAxMDAwMDAwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs | ||||
| b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT | ||||
| DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs | ||||
| b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw | ||||
| f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P | ||||
| IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo4GIMIGF | ||||
| MA4GA1UdDwEB/wQEAwIApDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBRB | ||||
| +YoiUjIm34/wBwHdJGE4Wufs/DAfBgNVHSMEGDAWgBTXXUgpaSwO9HOrQBxGqOOS | ||||
| FHsHEDAfBgNVHREEGDAWghRjbG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0B | ||||
| AQsDggIBACRqAC5EJEe+8ihv1WzCUMEMb7KtS0BqoNbdXE32ia66PgJSQmHcmeJd | ||||
| FI1UjL0DlljTM2tc+8KxR/1/qnKiI+W/D4wFTWOY/JWFOd15q7lXuKGl+8PMkAHF | ||||
| A145JCr6oZoO9G9wUwVUrbmXAbyPCOfzsEQ2+mD9F1ZpoEjzVhtGf0R+vnYrRw8j | ||||
| 4WCv5AIcYRAf7HZxbhMILF1bccNlqyUtdH+/MTHXpjkjJjA5KbsHBrAEfjAXkD7c | ||||
| WWOay6m7mVWb3PPFmGorP6t29baEETK9ZTZSrfD9rnExjjUCftWJEn0M4Pp98DvT | ||||
| br6+bg8jwtq73qdyOfNsC/Sod18UuHH7MTQA22yqAF5jIlcYtAHGlNnl+sDPZACs | ||||
| 369/Z9rOL9vPFL+Z3F/uJtqZzvN1QiCkj8jWzR0u9fh3eQwZADM2RwgwS4Gs2Ygh | ||||
| PsypDo33sFOwfX93KqKBsTHssn8SSDDaSnZ8bu1ATEdshbVieecuQx40UadPuJpw | ||||
| EPVqTR5AhviXQ9bKrTnU5T7EgkW9vNydkpLQQlMg3QE8hsndv4loGZbZGfNtqQHS | ||||
| /mg1t07S+7OEa4YaMW+wVOBOqTdW7OXlZFLfCcF5SYLM0SnlTMklRMxiqI4JqZXH | ||||
| 0thnUGD0JjfLX4rTaZUzT3lrXXWzpS2jzutXQkjGv4nhGGprIDuT | ||||
| -----END CERTIFICATE----- | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEkDCCA/ugAwIBAgIIWnP9jF/2nogwCwYJKoZIhvcNAQELMH0xCzAJBgNVBAYT | ||||
| AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv | ||||
| MRMwEQYDVQQKDApDbG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQG | ||||
| A1UEAwwNQ0ZTU0xfVEVTVF9DQTAeFw0xNDAzMDEwMDAwMDBaFw0xNDA0MTUwMDAw | ||||
| MDBaMIGMMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UE | ||||
| CxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET | ||||
| MBEGA1UECBMKQ2FsaWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5j | ||||
| b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDlCnV+vj0sVPy8SqHL | ||||
| AlI+xwnPhWgzj2VevD6Nz1Zu1BeQ5m5y4CWCf+GmRGTP7+a/C510Fw6rpmInB0Ng | ||||
| xxwQ2rC08fJtCnijlGH/VjEPIHY5lRaAomcM8Rgx6JOuv9BpZJKpr9pyUMV53JeW | ||||
| RbWuLH5nEMdyk9NpetS2gWxt4/D20QlhK/tHkROrcLmEUddwIGdwE8JzI88c77Fu | ||||
| u6pgMtHKvl4GGH0yvb4T7PvCdH8V2tCH7bt8roXd9MSyFVy7uORkfouip7EsVREU | ||||
| mlcY5EvpR141KXbZqiOQiusJ+u76mEUQNk8wCR1/CW/ii9v1BKOVjXwCfEtIXjg0 | ||||
| APJx1VNSSH6XoDpUETL+eQ4J0FL9XNbsDuYar7+zD0N1/5vSo3HLNRQR9f0lbsys | ||||
| sWBEN+CxK19xyPumr21Z0bU0f1B5H52VSF0q3I1Ju9wRo994a7YipdGcmZ2lChmT | ||||
| 7r3mzlBTYl3poU26q34v8wG9U7Jv4fsZJ+RGebDI+TR3QG6Yod06l9oEYZxWXBY7 | ||||
| STOs8wuTu3huSnan/IpWnV017Vsc61D5G+QrqcxZdXckt3anZKCF75JpUnJ7vuow | ||||
| TmmHlb8KIMa9mOvcuGX4P6mz8gTi2arl/aL27kj9Q0Jgv/y1ebe2Bx2P9TF6+VND | ||||
| DL3J/vSVlFeqLt2reAIBKnytLwIDAQABo4GIMIGFMA4GA1UdDwEB/wQEAwIApDAS | ||||
| BgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTXXUgpaSwO9HOrQBxGqOOSFHsH | ||||
| EDAfBgNVHSMEGDAWgBS4Xu+uZ1C31vMH5Wq+VbNnOg2SPjAfBgNVHREEGDAWghRj | ||||
| bG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0BAQsDgYEAfPLKCAHnPzgMYLX/ | ||||
| fWznVvOEFAAYZByPFx4QdMBbDZUtxHyvJIBs6PdxrdSuDwSiMqE7qQIi+jzzwGl9 | ||||
| fC7vf45B2zCX0OW51QL2oWNBdKlGgB+b2pwyME82lX/Pr7V1GY10u+ep1xdZDnch | ||||
| DaMsXjQQTJu0iuG3qKEuCmUwOmc= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										52
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| -----BEGIN PKCS7----- | ||||
| MIIJOAYJKoZIhvcNAQcCoIIJKTCCCSUCAQExADALBgkqhkiG9w0BBwGgggkLMIIE | ||||
| czCCAl2gAwIBAgIIDARj8BWNsscwCwYJKoZIhvcNAQELMIGMMQswCQYDVQQGEwJV | ||||
| UzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdpbmVl | ||||
| cmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5p | ||||
| YTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwMzAyMDAwMDAw | ||||
| WhcNMTkwNDAxMDAwMDAwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNsb3Vk | ||||
| RmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcTDVNh | ||||
| biBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNsb3Vk | ||||
| ZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGwf3F0 | ||||
| XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73PIXGy | ||||
| fNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo4GIMIGFMA4G | ||||
| A1UdDwEB/wQEAwIApDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBRB+Yoi | ||||
| UjIm34/wBwHdJGE4Wufs/DAfBgNVHSMEGDAWgBTXXUgpaSwO9HOrQBxGqOOSFHsH | ||||
| EDAfBgNVHREEGDAWghRjbG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0BAQsD | ||||
| ggIBACRqAC5EJEe+8ihv1WzCUMEMb7KtS0BqoNbdXE32ia66PgJSQmHcmeJdFI1U | ||||
| jL0DlljTM2tc+8KxR/1/qnKiI+W/D4wFTWOY/JWFOd15q7lXuKGl+8PMkAHFA145 | ||||
| JCr6oZoO9G9wUwVUrbmXAbyPCOfzsEQ2+mD9F1ZpoEjzVhtGf0R+vnYrRw8j4WCv | ||||
| 5AIcYRAf7HZxbhMILF1bccNlqyUtdH+/MTHXpjkjJjA5KbsHBrAEfjAXkD7cWWOa | ||||
| y6m7mVWb3PPFmGorP6t29baEETK9ZTZSrfD9rnExjjUCftWJEn0M4Pp98DvTbr6+ | ||||
| bg8jwtq73qdyOfNsC/Sod18UuHH7MTQA22yqAF5jIlcYtAHGlNnl+sDPZACs369/ | ||||
| Z9rOL9vPFL+Z3F/uJtqZzvN1QiCkj8jWzR0u9fh3eQwZADM2RwgwS4Gs2YghPsyp | ||||
| Do33sFOwfX93KqKBsTHssn8SSDDaSnZ8bu1ATEdshbVieecuQx40UadPuJpwEPVq | ||||
| TR5AhviXQ9bKrTnU5T7EgkW9vNydkpLQQlMg3QE8hsndv4loGZbZGfNtqQHS/mg1 | ||||
| t07S+7OEa4YaMW+wVOBOqTdW7OXlZFLfCcF5SYLM0SnlTMklRMxiqI4JqZXH0thn | ||||
| UGD0JjfLX4rTaZUzT3lrXXWzpS2jzutXQkjGv4nhGGprIDuTMIIEkDCCA/ugAwIB | ||||
| AgIIWnP9jF/2nogwCwYJKoZIhvcNAQELMH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI | ||||
| DApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRMwEQYDVQQKDApD | ||||
| bG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQGA1UEAwwNQ0ZTU0xf | ||||
| VEVTVF9DQTAeFw0xNDAzMDEwMDAwMDBaFw0xNDA0MTUwMDAwMDBaMIGMMQswCQYD | ||||
| VQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBF | ||||
| bmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2Fs | ||||
| aWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wggIiMA0GCSqG | ||||
| SIb3DQEBAQUAA4ICDwAwggIKAoICAQDlCnV+vj0sVPy8SqHLAlI+xwnPhWgzj2Ve | ||||
| vD6Nz1Zu1BeQ5m5y4CWCf+GmRGTP7+a/C510Fw6rpmInB0NgxxwQ2rC08fJtCnij | ||||
| lGH/VjEPIHY5lRaAomcM8Rgx6JOuv9BpZJKpr9pyUMV53JeWRbWuLH5nEMdyk9Np | ||||
| etS2gWxt4/D20QlhK/tHkROrcLmEUddwIGdwE8JzI88c77Fuu6pgMtHKvl4GGH0y | ||||
| vb4T7PvCdH8V2tCH7bt8roXd9MSyFVy7uORkfouip7EsVREUmlcY5EvpR141KXbZ | ||||
| qiOQiusJ+u76mEUQNk8wCR1/CW/ii9v1BKOVjXwCfEtIXjg0APJx1VNSSH6XoDpU | ||||
| ETL+eQ4J0FL9XNbsDuYar7+zD0N1/5vSo3HLNRQR9f0lbsyssWBEN+CxK19xyPum | ||||
| r21Z0bU0f1B5H52VSF0q3I1Ju9wRo994a7YipdGcmZ2lChmT7r3mzlBTYl3poU26 | ||||
| q34v8wG9U7Jv4fsZJ+RGebDI+TR3QG6Yod06l9oEYZxWXBY7STOs8wuTu3huSnan | ||||
| /IpWnV017Vsc61D5G+QrqcxZdXckt3anZKCF75JpUnJ7vuowTmmHlb8KIMa9mOvc | ||||
| uGX4P6mz8gTi2arl/aL27kj9Q0Jgv/y1ebe2Bx2P9TF6+VNDDL3J/vSVlFeqLt2r | ||||
| eAIBKnytLwIDAQABo4GIMIGFMA4GA1UdDwEB/wQEAwIApDASBgNVHRMBAf8ECDAG | ||||
| AQH/AgEBMB0GA1UdDgQWBBTXXUgpaSwO9HOrQBxGqOOSFHsHEDAfBgNVHSMEGDAW | ||||
| gBS4Xu+uZ1C31vMH5Wq+VbNnOg2SPjAfBgNVHREEGDAWghRjbG91ZGZsYXJlLWlu | ||||
| dGVyLmNvbTALBgkqhkiG9w0BAQsDgYEAfPLKCAHnPzgMYLX/fWznVvOEFAAYZByP | ||||
| Fx4QdMBbDZUtxHyvJIBs6PdxrdSuDwSiMqE7qQIi+jzzwGl9fC7vf45B2zCX0OW5 | ||||
| 1QL2oWNBdKlGgB+b2pwyME82lX/Pr7V1GY10u+ep1xdZDnchDaMsXjQQTJu0iuG3 | ||||
| qKEuCmUwOmehADEA | ||||
| -----END PKCS7----- | ||||
							
								
								
									
										56
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle_with_whitespace.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/bundle_with_whitespace.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
|      | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEczCCAl2gAwIBAgIIDARj8BWNsscwCwYJKoZIhvcNAQELMIGMMQswCQYDVQQG | ||||
| EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp | ||||
| bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv | ||||
| cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwMzAyMDAw | ||||
| MDAwWhcNMTkwNDAxMDAwMDAwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs | ||||
| b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT | ||||
| DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs | ||||
| b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw | ||||
| f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P | ||||
| IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo4GIMIGF | ||||
| MA4GA1UdDwEB/wQEAwIApDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBRB | ||||
| +YoiUjIm34/wBwHdJGE4Wufs/DAfBgNVHSMEGDAWgBTXXUgpaSwO9HOrQBxGqOOS | ||||
| FHsHEDAfBgNVHREEGDAWghRjbG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0B | ||||
| AQsDggIBACRqAC5EJEe+8ihv1WzCUMEMb7KtS0BqoNbdXE32ia66PgJSQmHcmeJd | ||||
| FI1UjL0DlljTM2tc+8KxR/1/qnKiI+W/D4wFTWOY/JWFOd15q7lXuKGl+8PMkAHF | ||||
| A145JCr6oZoO9G9wUwVUrbmXAbyPCOfzsEQ2+mD9F1ZpoEjzVhtGf0R+vnYrRw8j | ||||
| 4WCv5AIcYRAf7HZxbhMILF1bccNlqyUtdH+/MTHXpjkjJjA5KbsHBrAEfjAXkD7c | ||||
| WWOay6m7mVWb3PPFmGorP6t29baEETK9ZTZSrfD9rnExjjUCftWJEn0M4Pp98DvT | ||||
| br6+bg8jwtq73qdyOfNsC/Sod18UuHH7MTQA22yqAF5jIlcYtAHGlNnl+sDPZACs | ||||
| 369/Z9rOL9vPFL+Z3F/uJtqZzvN1QiCkj8jWzR0u9fh3eQwZADM2RwgwS4Gs2Ygh | ||||
| PsypDo33sFOwfX93KqKBsTHssn8SSDDaSnZ8bu1ATEdshbVieecuQx40UadPuJpw | ||||
| EPVqTR5AhviXQ9bKrTnU5T7EgkW9vNydkpLQQlMg3QE8hsndv4loGZbZGfNtqQHS | ||||
| /mg1t07S+7OEa4YaMW+wVOBOqTdW7OXlZFLfCcF5SYLM0SnlTMklRMxiqI4JqZXH | ||||
| 0thnUGD0JjfLX4rTaZUzT3lrXXWzpS2jzutXQkjGv4nhGGprIDuT | ||||
| -----END CERTIFICATE----- | ||||
|  | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEkDCCA/ugAwIBAgIIWnP9jF/2nogwCwYJKoZIhvcNAQELMH0xCzAJBgNVBAYT | ||||
| AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv | ||||
| MRMwEQYDVQQKDApDbG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQG | ||||
| A1UEAwwNQ0ZTU0xfVEVTVF9DQTAeFw0xNDAzMDEwMDAwMDBaFw0xNDA0MTUwMDAw | ||||
| MDBaMIGMMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UE | ||||
| CxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET | ||||
| MBEGA1UECBMKQ2FsaWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5j | ||||
| b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDlCnV+vj0sVPy8SqHL | ||||
| AlI+xwnPhWgzj2VevD6Nz1Zu1BeQ5m5y4CWCf+GmRGTP7+a/C510Fw6rpmInB0Ng | ||||
| xxwQ2rC08fJtCnijlGH/VjEPIHY5lRaAomcM8Rgx6JOuv9BpZJKpr9pyUMV53JeW | ||||
| RbWuLH5nEMdyk9NpetS2gWxt4/D20QlhK/tHkROrcLmEUddwIGdwE8JzI88c77Fu | ||||
| u6pgMtHKvl4GGH0yvb4T7PvCdH8V2tCH7bt8roXd9MSyFVy7uORkfouip7EsVREU | ||||
| mlcY5EvpR141KXbZqiOQiusJ+u76mEUQNk8wCR1/CW/ii9v1BKOVjXwCfEtIXjg0 | ||||
| APJx1VNSSH6XoDpUETL+eQ4J0FL9XNbsDuYar7+zD0N1/5vSo3HLNRQR9f0lbsys | ||||
| sWBEN+CxK19xyPumr21Z0bU0f1B5H52VSF0q3I1Ju9wRo994a7YipdGcmZ2lChmT | ||||
| 7r3mzlBTYl3poU26q34v8wG9U7Jv4fsZJ+RGebDI+TR3QG6Yod06l9oEYZxWXBY7 | ||||
| STOs8wuTu3huSnan/IpWnV017Vsc61D5G+QrqcxZdXckt3anZKCF75JpUnJ7vuow | ||||
| TmmHlb8KIMa9mOvcuGX4P6mz8gTi2arl/aL27kj9Q0Jgv/y1ebe2Bx2P9TF6+VND | ||||
| DL3J/vSVlFeqLt2reAIBKnytLwIDAQABo4GIMIGFMA4GA1UdDwEB/wQEAwIApDAS | ||||
| BgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTXXUgpaSwO9HOrQBxGqOOSFHsH | ||||
| EDAfBgNVHSMEGDAWgBS4Xu+uZ1C31vMH5Wq+VbNnOg2SPjAfBgNVHREEGDAWghRj | ||||
| bG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0BAQsDgYEAfPLKCAHnPzgMYLX/ | ||||
| fWznVvOEFAAYZByPFx4QdMBbDZUtxHyvJIBs6PdxrdSuDwSiMqE7qQIi+jzzwGl9 | ||||
| fC7vf45B2zCX0OW51QL2oWNBdKlGgB+b2pwyME82lX/Pr7V1GY10u+ep1xdZDnch | ||||
| DaMsXjQQTJu0iuG3qKEuCmUwOmc= | ||||
| -----END CERTIFICATE----- | ||||
|  | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEmzCCA4OgAwIBAgIMAMSvNBgypwaaSQ5iMA0GCSqGSIb3DQEBBQUAMIGMMQsw | ||||
| CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy | ||||
| YW5jaXNjbzETMBEGA1UEChMKQ0ZTU0wgVEVTVDEbMBkGA1UEAxMSQ0ZTU0wgVEVT | ||||
| VCBSb290IENBMR4wHAYJKoZIhvcNAQkBFg90ZXN0QHRlc3QubG9jYWwwHhcNMTIx | ||||
| MjEyMDIxMDMxWhcNMjIxMDIxMDIxMDMxWjCBjDELMAkGA1UEBhMCVVMxEzARBgNV | ||||
| BAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAoT | ||||
| CkNGU1NMIFRFU1QxGzAZBgNVBAMTEkNGU1NMIFRFU1QgUm9vdCBDQTEeMBwGCSqG | ||||
| SIb3DQEJARYPdGVzdEB0ZXN0LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A | ||||
| MIIBCgKCAQEAsRp1xSfIDoD/40Bo4Hls3sFn4dav5NgxbZGpVyGF7dJI9u0eEnL4 | ||||
| BUGssPaUFLWC83CZxujUEiEfE0oKX+uOhhGv3+j5xSTNM764m2eSiN53cdZtK05d | ||||
| hwq9uS8LtjKOQeN1mQ5qmiqxBMdjkKgMsVw5lMCgoYKo57kaKFyXzdpNVDzqw+pt | ||||
| HWmuNtDQjK3qT5Ma06mYPmIGYhIZYLY7oJGg9ZEaNR0GIw4zIT5JRsNiaSb5wTLw | ||||
| aa0n/4vLJyVjLJcYmJBvZWj8g+taK+C4INu/jGux+bmsC9hq14tbOaTNAn/NE0qN | ||||
| 8oHwcRBEqfOdEYdZkxI5NWPiKNW/Q+AeXQIDAQABo4H6MIH3MB0GA1UdDgQWBBS3 | ||||
| 0veEuqg51fusEM4p/YuWpBPsvTCBxAYDVR0jBIG8MIG5gBS30veEuqg51fusEM4p | ||||
| /YuWpBPsvaGBkqSBjzCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju | ||||
| aWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAoTCkNGU1NMIFRFU1Qx | ||||
| GzAZBgNVBAMTEkNGU1NMIFRFU1QgUm9vdCBDQTEeMBwGCSqGSIb3DQEJARYPdGVz | ||||
| dEB0ZXN0LmxvY2FsggwAxK80GDKnBppJDmIwDwYDVR0TBAgwBgEB/wIBADANBgkq | ||||
| hkiG9w0BAQUFAAOCAQEAJ7r1EZYDwed6rS0+YKHdkRGRQ5Rz6A9DIVBPXrSMAGj3 | ||||
| F5EF2m/GJbhpVbnNJTVlgP9DDyabOZNxzdrCr4cHMkYYnocDdgAodnkw6GZ/GJTc | ||||
| depbVTR4TpihFNzeDEGJePrEwM1DouGswpu97jyuCYZ3z1a60+a+3C1GwWaJ7Aet | ||||
| Uqm+yLTUrMISsfnDPqJdM1NeqW3jiZ4IgcqJkieCCSpag9Xuzrp9q6rjmePvlQkv | ||||
| qz020JGg6VijJ+c6Tf5y0XqbAhkBTqYtVamu9gEth9utn12EhdNjTZMPKMjjgFUd | ||||
| H0N6yOEuQMl4ky7RxZBM0iPyeob6i4z2LEQilgv9MQ== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ca_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ca_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| -----BEGIN PRIVATE KEY----- | ||||
| MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxGnXFJ8gOgP/j | ||||
| QGjgeWzewWfh1q/k2DFtkalXIYXt0kj27R4ScvgFQayw9pQUtYLzcJnG6NQSIR8T | ||||
| Sgpf646GEa/f6PnFJM0zvribZ5KI3ndx1m0rTl2HCr25Lwu2Mo5B43WZDmqaKrEE | ||||
| x2OQqAyxXDmUwKChgqjnuRooXJfN2k1UPOrD6m0daa420NCMrepPkxrTqZg+YgZi | ||||
| EhlgtjugkaD1kRo1HQYjDjMhPklGw2JpJvnBMvBprSf/i8snJWMslxiYkG9laPyD | ||||
| 61or4Lgg27+Ma7H5uawL2GrXi1s5pM0Cf80TSo3ygfBxEESp850Rh1mTEjk1Y+Io | ||||
| 1b9D4B5dAgMBAAECggEAKHhjcSomDSptTwDo9mLI/h40HudwSlsc8GzYxZBjinUD | ||||
| N2n39T9QbeMUE1xFenX/9qFEgq+xxnLLJx1EQacSapCgIAqdCO/f9HMgvGJumdg8 | ||||
| c0cMq1i9Bp7tu+OESZ5D48qWlOM2eQRIb08g8W11eRIaFmPuUPoKnuktkQuXpPJc | ||||
| YbS/+JuA8SDwe6sV0cMCQuS+iHFfeGwWCKrDUkhLwcL3waW3od2XFyOeFFWFhl0h | ||||
| HmM/mWKRuRdqR7hrmArTwFZVkB+o/1ywVYXIv+JQm0eNZ5PKLNJGL2f5oxbMR/JI | ||||
| AoK0bAlJmYaFp96h1KpbPwLEL/0hHSWA7sAyJIgQAQKBgQDaEAZor/w4ZUTekT1+ | ||||
| cbId0yA+ikDXQOfXaNCSh9Pex+Psjd5zVVOqyVFJ29daRju3d7rmpN4Cm5V4h0l1 | ||||
| /2ad207rjCAnpCHtaddJWNyJzF2IL2IaoCZQRp0k7zOjBGQpoWDTwBaEin5CCv3P | ||||
| kkdQkKz6FDP1xskHSLZr21/QCQKBgQDP6jXutEgGjf3yKpMFk/69EamJdon8clbt | ||||
| hl7cOyWtobnZhdOWVZPe00Oo3Jag2aWgFFsm3EtwnUCnR4d4+fXRKS2LkhfIUZcz | ||||
| cKy17Ileggdd8UGhL4RDrF/En9tJL86WcVkcoOrqLcGB2FLWrVhVpHFK74eLMCH/ | ||||
| uc/+ioPItQKBgHYoDsD08s7AGMQcoNx90MyWVLduhFnegoFW+wUa8jOZzieka6/E | ||||
| wVQeR5yksZjpy3vLNYu6M83n7eLkM2rrm/fXGHlLcTTpm7SgEBZfPwivotKjEh5p | ||||
| PrlqucWEk082lutz1RqHz+u7e1Rfzk2F7nx6GDBdeBYpw03eGXJx6QW5AoGBAIJq | ||||
| 4puyAEAET1fZNtHX7IGCk7sDXTi6LCbgE57HhzHr8V0t4fQ6CABMuvMwM1gATjEk | ||||
| s6yjoLqqGUUUzDipanViBAy5fiuManC868lN7zkWDTLzQ3ytBqVAee4na/DziP27 | ||||
| ae9YTSLJwskE/alloLRP6zTbHUXE0n7LelmrX1DFAoGBAMFLl+Lu+WFgCHxBjn43 | ||||
| rHpJbQZQmsFhAMhkN4hsj6dJfAGn2gRLRiVRAika+8QF65xMZiVQWUVSUZADWERi | ||||
| 0SXGjzN1wYxO3Qzy3LYwws6fxFAq5lo79eb38yFT2lHdqK3x/QgiDSRVl+R6cExV | ||||
| xQB518/lp2eIeMpglWByDwJX | ||||
| -----END PRIVATE KEY----- | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIB7DCCAZKgAwIBAgIIE/Qz49ebG7kwCgYIKoZIzj0EAwIwTDELMAkGA1UEBhMC | ||||
| VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x | ||||
| EDAOBgNVBAoTB2FjbWUuY28wHhcNMTcwNTIzMTk1MTQ0WhcNMTcwODIzMDE1NjQ0 | ||||
| WjBMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN | ||||
| U2FuIEZyYW5jaXNjbzEQMA4GA1UEChMHYWNtZS5jbzBZMBMGByqGSM49AgEGCCqG | ||||
| SM49AwEHA0IABEW8F+k/avvdBm/KRsuDnTZ3p+VuVdsqDF+aD9nIYeOhx5sj574y | ||||
| hEIZOpgbEsi3BvqY63y2jYyPFodf25+CA9GjXjBcMA4GA1UdDwEB/wQEAwIFoDAd | ||||
| BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNV | ||||
| HQ4EFgQUzDpu+HN89EC1M8aNl7f0Ln5JnnIwCgYIKoZIzj0EAwIDSAAwRQIgC4/r | ||||
| urbw/pzE3LDA6GpIts6TVyzgftLLEfU2BzQsjp0CIQDo+sn8t7XC6JN4KKRr2ABl | ||||
| ZI+JifgG+2KCy9ln2LxGJQ== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										14
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| -----BEGIN PKCS7----- | ||||
| MIICHQYJKoZIhvcNAQcCoIICDjCCAgoCAQExADALBgkqhkiG9w0BBwGgggHwMIIB | ||||
| 7DCCAZKgAwIBAgIIE/Qz49ebG7kwCgYIKoZIzj0EAwIwTDELMAkGA1UEBhMCVVMx | ||||
| EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEDAO | ||||
| BgNVBAoTB2FjbWUuY28wHhcNMTcwNTIzMTk1MTQ0WhcNMTcwODIzMDE1NjQ0WjBM | ||||
| MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu | ||||
| IEZyYW5jaXNjbzEQMA4GA1UEChMHYWNtZS5jbzBZMBMGByqGSM49AgEGCCqGSM49 | ||||
| AwEHA0IABEW8F+k/avvdBm/KRsuDnTZ3p+VuVdsqDF+aD9nIYeOhx5sj574yhEIZ | ||||
| OpgbEsi3BvqY63y2jYyPFodf25+CA9GjXjBcMA4GA1UdDwEB/wQEAwIFoDAdBgNV | ||||
| HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E | ||||
| FgQUzDpu+HN89EC1M8aNl7f0Ln5JnnIwCgYIKoZIzj0EAwIDSAAwRQIgC4/rurbw | ||||
| /pzE3LDA6GpIts6TVyzgftLLEfU2BzQsjp0CIQDo+sn8t7XC6JN4KKRr2ABlZI+J | ||||
| ifgG+2KCy9ln2LxGJaEAMQA= | ||||
| -----END PKCS7----- | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert_with_whitespace.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/cert_with_whitespace.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
|  | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIB7DCCAZKgAwIBAgIIE/Qz49ebG7kwCgYIKoZIzj0EAwIwTDELMAkGA1UEBhMC | ||||
| VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x | ||||
| EDAOBgNVBAoTB2FjbWUuY28wHhcNMTcwNTIzMTk1MTQ0WhcNMTcwODIzMDE1NjQ0 | ||||
| WjBMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN | ||||
| U2FuIEZyYW5jaXNjbzEQMA4GA1UEChMHYWNtZS5jbzBZMBMGByqGSM49AgEGCCqG | ||||
| SM49AwEHA0IABEW8F+k/avvdBm/KRsuDnTZ3p+VuVdsqDF+aD9nIYeOhx5sj574y | ||||
| hEIZOpgbEsi3BvqY63y2jYyPFodf25+CA9GjXjBcMA4GA1UdDwEB/wQEAwIFoDAd | ||||
| BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNV | ||||
| HQ4EFgQUzDpu+HN89EC1M8aNl7f0Ln5JnnIwCgYIKoZIzj0EAwIDSAAwRQIgC4/r | ||||
| urbw/pzE3LDA6GpIts6TVyzgftLLEfU2BzQsjp0CIQDo+sn8t7XC6JN4KKRr2ABl | ||||
| ZI+JifgG+2KCy9ln2LxGJQ== | ||||
| -----END CERTIFICATE----- | ||||
|  | ||||
							
								
								
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ecdsa256.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/ecdsa256.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIBgTCCASgCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBn9Ldie6BOcMHezn2dPuYqW | ||||
| z/NoLYMLGNBqhOxUyEidYClI0JW2pWyUgT3A2UazFp1WgE94y7Z+2YlfRz+vcrKg | ||||
| PzA9BgkqhkiG9w0BCQ4xMDAuMCwGA1UdEQQlMCOCDmNsb3VkZmxhcmUuY29tghF3 | ||||
| d3djbG91ZGZsYXJlLmNvbTAKBggqhkjOPQQDAgNHADBEAiBM+QRxe8u6rkdr10Jy | ||||
| cxbR6NxrGrNeg5QqiOqF96JEmgIgDbtjd5e3y3I8W/+ih2us3WtMxgnTXfqPd48i | ||||
| VLcv28Q= | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty_pkcs7.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty_pkcs7.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/empty_pkcs7.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| -----BEGIN PKCS7----- | ||||
| MCcGCSqGSIb3DQEHAqAaMBgCAQExADALBgkqhkiG9w0BBwGgAKEAMQA= | ||||
| -----END PKCS7----- | ||||
							
								
								
									
										2
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/emptycert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/emptycert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| -----END CERTIFICATE-----LSKFSKLF | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/emptypasswordpkcs12.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/emptypasswordpkcs12.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										30
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/enc_priv_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/enc_priv_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| Proc-Type: 4,ENCRYPTED | ||||
| DEK-Info: AES-128-CBC,90B8A5792FA2FE75B2053582F3DF394F | ||||
|  | ||||
| yVY2xuth5fdJBg9gg+6eP3qTsr0CJ2mGEDW6rvYmYuATSRF1hVERrsznxJYjYLaw | ||||
| JHec8FVr78y4aXxI/aFzlxLkS8f12WjTtIhzHwhzgSJDwVOXSRphnLAeHWnhEKLe | ||||
| 7kO+vzoTPIc3ECwdvtr6//z2tP1/sac+yIhL6C+x2rS5hFHhmDUXtILPxxfHJCiM | ||||
| qtKiiOZz3W6008CeJMC9ZPlKHDvpq7aIL4rfVP/GkZ+/teQkgWNpMxac7+gWLKuK | ||||
| 109v6pu+8KT49D6SMsaZPvAb5PXcIB79ZCPI1JX0V26CKcswba4RHG/h1xifwyAF | ||||
| OIvmK29mmFqbx5GPlUefRUuPwRJKCXFiK6LTdhCwLYodtXde4ibvOFYy4onGoVax | ||||
| I5WVaOhQMqp+mxA6z7odrIvuFcQGixIA+peaaSbpNZSZGuxRvVefcdxPbJ+26Ijs | ||||
| wq8uyalbwhKtjPTPNkMaaYzJdWS7wd2DS4RM9JT8Y1h6NTftCY3c+/txOlt5pQzW | ||||
| T8n+NTd4o+PFOHzMnmEnrtf9Y/SSzXDB2OPCD95YdIXItQDdKcjK0NmnY8GNfkWL | ||||
| G30NJNy3/DR7Sa5u4xuqNgcgTFhgZaOQ1IVB3p5VjknqAX3gWFu2DrqzbH45071A | ||||
| He7VbdbzBpMHI2EdiCVOuK9fD/5sv25u9vVC2NHtG/YcoEQv+RB52TNHn9kdiMj1 | ||||
| gLaywPqGjFmaPxI0xX07BrL+D9RruUT1GAEyw4JAHuJZIyq3+V98wmV/pEqwc7hp | ||||
| 8WuSi6YddetfF4NPA5cGWt8qZ1it+wD/1ydQEAQsxdANqi0XVudYpYox02EoRS02 | ||||
| up0sd9zqz83pN9RyOOKtGcHdt85gb9DYRVeff1UszMaoVULxqxYetwtzpiHn6grL | ||||
| DmnSk+DYgvXKOVt8tmSJysDTumhK1VN3xb34TYYJxeBOQJLzWFjGSELEpphZAQSj | ||||
| rS4OM1FwoP48wvASGiWD4VUJ6v+6F+NDvJr01S+zWGLg1EeUZJmXGHW5GrGd4Kgx | ||||
| 3rdeOsrED9oXKp2cpgx9avXJ9upixja9MbAPp7RkSyeHMPvsuaI44xvOP3f0crmG | ||||
| d/5CdBKVT7nFaeTGSx/78kHb3VJyopAMm9k0V3CheKwBXXSbXmV1+0muBxMHsEI3 | ||||
| aEKaI0y5cDfTewzo/U0l0kGtxF6kUPN1pdjFpAvssRlkGttFOC2nWxHwaNHpn7Kq | ||||
| gFAlN6P4cyB6kb+LvckIYTZ/tV39dx7PfL0KG5TWjJ4a9GSoL1IrAhQq+Qv6oUEt | ||||
| 1vlejZoKyZ/35fni0fmeYNho+pCPimm6l+sHTuXkrWgGLr0S9O00HFLz11D7R4o9 | ||||
| 7mF4JkMNztT+ENOdT4xQBi3OGjRGMwtE6PsQPfDeu13Vq6eDtdEGUdhW1kAsGnBi | ||||
| eJRuysnGpnoWofJ7yS0+DhnS4GAVi907TMrQWwmez9V4CXl4NBc8X9T69TFL2LsW | ||||
| 2KU9NUXdiCRZqZHD41gd3+RuRA/oXh50V9oaow+uepwYKTFyzde5IH1/DgBd7tOd | ||||
| Fa2fM5/zSA0uFPRb3yCVhRg5d6J9t5yaPAz7Jp0D1mDDGsMBD1O/FYJvWoANEwUX | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										48
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messed_up_bundle.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messed_up_bundle.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEczCCAl2gAwIBAgIIDARj8BWNsscwCwYJKoZIhvcNAQELMIGMMQswCQYDVQQG | ||||
| EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp | ||||
| bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv | ||||
| cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwMzAyMDAw | ||||
| MDAwWhcNMTkwNDAxMDAwMDAwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs | ||||
| b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT | ||||
| FHsHEDAfBgNVHREEGDAWghRjbG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0B | ||||
| AQsDggIBACRqAC5EJEe+8ihv1WzCUMEMb7KtS0BqoNbdXE32ia66PgJSQmHcmeJd | ||||
| FI1UjL0DlljTM2tc+8KxR/1/qnKiI+W/D4wFTWOY/JWFOd15q7lXuKGl+8PMkAHF | ||||
| A145JCr6oZoO9G9wUwVUrbmXAbyPCOfzsEQ2+mD9F1ZpoEjzVhtGf0R+vnYrRw8j | ||||
| 4WCv5AIcYRAf7HZxbhMILF1bccNlqyUtdH+/MTHXpjkjJjA5KbsHBrAEfjAXkD7c | ||||
| WWOay6m7mVWb3PPFmGorP6t29baEETK9ZTZSrfD9rnExjjUCftWJEn0M4Pp98DvT | ||||
| br6+bg8jwtq73qdyOfNsC/Sod18UuHH7MTQA22yqAF5jIlcYtAHGlNnl+sDPZACs | ||||
| 369/Z9rOL9vPFL+Z3F/uJtqZzvN1QiCkj8jWzR0u9fh3eQwZADM2RwgwS4Gs2Ygh | ||||
| PsypDo33sFOwfX93KqKBsTHssn8SSDDaSnZ8bu1ATEdshbVieecuQx40UadPuJpw | ||||
| EPVqTR5AhviXQ9bKrTnU5T7EgkW9vNydkpLQQlMg3QE8hsndv4loGZbZGfNtqQHS | ||||
| /mg1t07S+7OEa4YaMW+wVOBOqTdW7OXlZFLfCcF5SYLM0SnlTMklRMxiqI4JqZXH | ||||
| 0thnUGD0JjfLX4rTaZUzT3lrXXWzpS2jzutXQkjGv4nhGGprIDuT | ||||
| -----END CERTIFICATE----- | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEkDCCA/ugAwIBAgIIWnP9jF/2nogwCwYJKoZIhvcNAQELMH0xCzAJBgNVBAYT | ||||
| AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv | ||||
| MRMwEQYDVQQKDApDbG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQG | ||||
| A1UEAwwNQ0ZTU0xfVEVTVF9DQTAeFw0xNDAzMDEwMDAwMDBaFw0xNDA0MTUwMDAw | ||||
| MDBaMIGMMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UE | ||||
| CxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET | ||||
| MBEGA1UECBMKQ2FsaWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5j | ||||
| b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDlCnV+vj0sVPy8SqHL | ||||
| AlI+xwnPhWgzj2VevD6Nz1Zu1BeQ5m5y4CWCf+GmRGTP7+a/C510Fw6rpmInB0Ng | ||||
| xxwQ2rC08fJtCnijlGH/VjEPIHY5lRaAomcM8Rgx6JOuv9BpZJKpr9pyUMV53JeW | ||||
| RbWuLH5nEMdyk9NpetS2gWxt4/D20QlhK/tHkROrcLmEUddwIGdwE8JzI88c77Fu | ||||
| u6pgMtHKvl4GGH0yvb4T7PvCdH8V2tCH7bt8roXd9MSyFVy7uORkfouip7EsVREU | ||||
| mlcY5EvpR141KXbZqiOQiusJ+u76mEUQNk8wCR1/CW/ii9v1BKOVjXwCfEtIXjg0 | ||||
| APJx1VNSSH6XoDpUETL+eQ4J0FL9XNbsDuYar7+zD0N1/5vSo3HLNRQR9f0lbsys | ||||
| sWBEN+CxK19xyPumr21Z0bU0f1B5H52VSF0q3I1Ju9wRo994a7YipdGcmZ2lChmT | ||||
| 7r3mzlBTYl3poU26q34v8wG9U7Jv4fsZJ+RGebDI+TR3QG6Yod06l9oEYZxWXBY7 | ||||
| STOs8wuTu3huSnan/IpWnV017Vsc61D5G+QrqcxZdXckt3anZKCF75JpUnJ7vuow | ||||
| TmmHlb8KIMa9mOvcuGX4P6mz8gTi2arl/aL27kj9Q0Jgv/y1ebe2Bx2P9TF6+VND | ||||
| DL3J/vSVlFeqLt2reAIBKnytLwIDAQABo4GIMIGFMA4GA1UdDwEB/wQEAwIApDAS | ||||
| BgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTXXUgpaSwO9HOrQBxGqOOSFHsH | ||||
| EDAfBgNVHSMEGDAWgBS4Xu+uZ1C31vMH5Wq+VbNnOg2SPjAfBgNVHREEGDAWghRj | ||||
| bG91ZGZsYXJlLWludGVyLmNvbTALBgkqhkiG9w0BAQsDgYEAfPLKCAHnPzgMYLX/ | ||||
| fWznVvOEFAAYZByPFx4QdMBbDZUtxHyvJIBs6PdxrdSuDwSiMqE7qQIi+jzzwGl9 | ||||
| fC7vf45B2zCX0OW51QL2oWNBdKlGgB+b2pwyME82lX/Pr7V1GY10u+ep1xdZDnch | ||||
| DaMsXjQQTJu0iuG3qKEuCmUwOmc= | ||||
| -----END CERTIFICATE----- | ||||
| SDFSDKjkfdlsdfj | ||||
							
								
								
									
										20
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messed_up_priv_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messed_up_priv_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| MIIEowIBAAKCAQEAvGKyz9ZzIXI/BFrtqbVQMmKQkPZGndyfV3AzeSb2ulbS/s5k | ||||
| yNJMH/jKZiSCvZiJNnW+JNlJrgLxORMmPStPz/N/0L0vCTotQKZUiaBttFgHgobQ | ||||
| LFsbMnumt9It5W/uOwgWI9binuzvqyPXywLlYwOq3jkOmA22ymhflzRrl6a3jzcY | ||||
| hT9evxHl0gV4bN7KZ5p4wK/UUuG1uMEQLw87lUwRRHeW3ZG52VL38+redka+f5pa | ||||
| SGKyG5j0oe1NPLqAjckNgqvDdPMY2gicmCq0VSLzTNpHRsURTUSJvC/iv34vVfba | ||||
| gIYgTvm8BvGbJSlZqP4kEVlOfd3vmB0ttUeoDwIDAQABAoIBAHZdpXCFlA1d1U6N | ||||
| O2s4a01dNOyAcVpa9xtfelgTLU9jomtLj3PG/uHP1oxbQHKUVxKK5JAOnwbg/mQY | ||||
| LhydDCbjHlovpFAt56UJXXCkBoocDYvr3P0huXL80oIJY6EXtR4ONKsMJ5Qn12c2 | ||||
| vC3ogey2rzO1sf/EDigbcIR3AWtk1Tx8ZDUooktOFypIsDQgjjxXiURGssAlMPSh | ||||
| 6GVgO4JRRG6oRxEna7yDe7izmh/hC5sxSYLsEikCgYEAsBHhb/Qef5obRCSrfFuQ | ||||
| 41P7MCtGrXVxKD3iCDGQCzVbEbYGpmZnGsXSaHljp2FtnamaGGEudYziozGKPHjs | ||||
| pbTbsLIDbmNwxz1WcaZ1iyIjtOxcAEqDod8hY4hL6SaxypwTHn4Ydbw2NGzp11Eg | ||||
| Di4SVL82utjycATdKFvBzdsCgYB/3M+GMrt0Sh87rKcQLdL709Kzjcfhvm4HjIbJ | ||||
| GSXGPCZaYMKaXRTdNAjtRKxMawc9qcf0xSBEHL0GkB158TzusDQtjP1anTcYOnl6 | ||||
| GsO4bRivp314iNlP4r3S3bIXqBxCGH3HbrvpdPFAN//qjYmAki2lFQZywfvbQOE8 | ||||
| oFQHwQKBgHqJkTck2DGlXQIwA7jirLggISXjSPlsG4w4LuhY9ivyNKLUi4x5k1cE | ||||
| bX7SrRtJErQ1WaDN4TFG25xnysi5h+aPinuySatd0XmA5+dE1YjTqqShMO+lUpzi | ||||
| PrOQl6Eva/uw5BDAcUH4AaXTNRvvtXQptUil9qXyOh6fszikA9Mm | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messedupcert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/messedupcert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIB7jCCAVmgAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD | ||||
| bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTEyMDkwNzIyMDAwNFoXDTEzMDkwNzIy | ||||
| MDUwNFowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGd | ||||
| MAsGCSqGSIb3DQEBAQOBjQAwgYkCgYEAm6f+jkP2t5q/vM0YAUZZkhq/EAYD+L1C | ||||
| cqhEvLFbu3MCAwEAAaMyMDAwDgYDVR0PAQH/BAQDAgCgMA0GA1UdDgQGBAQBAgME | ||||
| MA8GA1UdIwQIMAaABAECAwQwCwYJKoZIhvcNAQEFA4GBABndWRIcfi+QB9Sakr+m | ||||
| dYnXTgYCnFio53L2Z+6EHTGG+rEhWtUEGhL4p4pzXX4siAnjWvwcgXTo92cafcfi | ||||
| uB7wRfK+NL9CTJdpN6cdL+fiNHzH8hsl3bj1nL0CSmdn2hkUWVLbLhSgWlib/I8O | ||||
| aq+K7aVrgHkPnWeRiG6tl+ZA | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/multiplecerts.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/multiplecerts.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										9
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/noheadercert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/noheadercert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| MIIB7jCCAVmgAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD | ||||
| bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTEyMDkwNzIyMDAwNFoXDTEzMDkwNzIy | ||||
| MDUwNFowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGd | ||||
| MAsGCSqGSIb3DQEBAQOBjQAwgYkCgYEAm6f+jkP2t5q/vM0YAUZZkhq/EAYD+L1C | ||||
| cqhEvLFbu3MCAwEAAaMyMDAwDgYDVR0PAQH/BAQDAgCgMA0GA1UdDgQGBAQBAgME | ||||
| MA8GA1UdIwQIMAaABAECAwQwCwYJKoZIhvcNAQEFA4GBABndWRIcfi+QB9Sakr+m | ||||
| dYnXTgYCnFio53L2Z+6EHTGG+rEhWtUEGhL4p4pzXX4siAnjWvwcgXTo92cafcfi | ||||
| uB7wRfK+NL9CTJdpN6cdL+fiNHzH8hsl3bj1nL0CSmdn2hkUWVLbLhSgWlib/I8O | ||||
| aq+K7aVrgHkPnWeRiG6tl+ZA | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/passwordpkcs12.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/passwordpkcs12.p12
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/priv_rsa_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/priv_rsa_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| MIIEowIBAAKCAQEAvGKyz9ZzIXI/BFrtqbVQMmKQkPZGndyfV3AzeSb2ulbS/s5k | ||||
| yNJMH/jKZiSCvZiJNnW+JNlJrgLxORMmPStPz/N/0L0vCTotQKZUiaBttFgHgobQ | ||||
| LFsbMnumt9It5W/uOwgWI9binuzvqyPXywLlYwOq3jkOmA22ymhflzRrl6a3jzcY | ||||
| hT9evxHl0gV4bN7KZ5p4wK/UUuG1uMEQLw87lUwRRHeW3ZG52VL38+redka+f5pa | ||||
| SGKyG5j0oe1NPLqAjckNgqvDdPMY2gicmCq0VSLzTNpHRsURTUSJvC/iv34vVfba | ||||
| gIYgTvm8BvGbJSlZqP4kEVlOfd3vmB0ttUeoDwIDAQABAoIBAHZdpXCFlA1d1U6N | ||||
| O2s4a01dNOyAcVpa9xtfelgTLU9jomtLj3PG/uHP1oxbQHKUVxKK5JAOnwbg/mQY | ||||
| LhydDCbjHlovpFAt56UJXXCkBoocDYvr3P0huXL80oIJY6EXtR4ONKsMJ5Qn12c2 | ||||
| vC3ogey2rzO1sf/EDigbcIR3AWtk1Tx8ZDUooktOFypIsDQgjjxXiURGssAlMPSh | ||||
| 1BFz4StRUK4bESaja0GiHwbuxHa+XYEBlK5OqMo/fpWqpgHhV/42+7wdcBMJsMr8 | ||||
| rFBe6m+r6TTbLSGJNowyd05XrjoAI35qduckpJ3Voun90i4ynTudjdJ/vHpIqB74 | ||||
| qQLFW2ECgYEA+GSRVqobaKKakNUFGmK0I5T5Tikz5f137YXXER6aLtDQNiSrlXNi | ||||
| 0aphkC/EfRO3oNvamq5+55bmmgDVoNNPDfpajKz+LZyG8GC2EXlTKO0hZS64KRRl | ||||
| C+bd+ZsYiUDImNVRbIHN82f+BQgsgXlTaWpBOrEqmoePO/J44O4eX3cCgYEAwieq | ||||
| amY4UaY+MhWPJFRK1y9M3hM8+N9N/35CFewQUdFJosC6vVQ4t8jNkSOxVQdgbNwE | ||||
| i/bTBgIwg82JJYbBUPuCVeTT3i6zxymf/FLumrI73URD81IN6FiH1skg0hSFrvs0 | ||||
| 6GVgO4JRRG6oRxEna7yDe7izmh/hC5sxSYLsEikCgYEAsBHhb/Qef5obRCSrfFuQ | ||||
| 41P7MCtGrXVxKD3iCDGQCzVbEbYGpmZnGsXSaHljp2FtnamaGGEudYziozGKPHjs | ||||
| pbTbsLIDbmNwxz1WcaZ1iyIjtOxcAEqDod8hY4hL6SaxypwTHn4Ydbw2NGzp11Eg | ||||
| Di4SVL82utjycATdKFvBzdsCgYB/3M+GMrt0Sh87rKcQLdL709Kzjcfhvm4HjIbJ | ||||
| GSXGPCZaYMKaXRTdNAjtRKxMawc9qcf0xSBEHL0GkB158TzusDQtjP1anTcYOnl6 | ||||
| GsO4bRivp314iNlP4r3S3bIXqBxCGH3HbrvpdPFAN//qjYmAki2lFQZywfvbQOE8 | ||||
| oFQHwQKBgHqJkTck2DGlXQIwA7jirLggISXjSPlsG4w4LuhY9ivyNKLUi4x5k1cE | ||||
| bX7SrRtJErQ1WaDN4TFG25xnysi5h+aPinuySatd0XmA5+dE1YjTqqShMO+lUpzi | ||||
| PrOQl6Eva/uw5BDAcUH4AaXTNRvvtXQptUil9qXyOh6fszikA9Mm | ||||
| -----END RSA PRIVATE KEY----- | ||||
|  | ||||
							
								
								
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/private_ecdsa_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/private_ecdsa_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| -----BEGIN EC PRIVATE KEY----- | ||||
| MGgCAQEEHCGXsrNo2xfy8+zd4Pzj8rcQ5KqQO43au1t/7nugBwYFK4EEACGhPAM6 | ||||
| AASJodCTtj5aYXnWxMiYhwjEgNQJJbNzJFEbsGJX9pCWZC673ammTWFHMjnMPkS/ | ||||
| 9eU5YeW40BHqfw== | ||||
| -----END EC PRIVATE KEY----- | ||||
							
								
								
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/rsa-old.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/rsa-old.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| -----BEGIN NEW CERTIFICATE REQUEST----- | ||||
| MIIDCTCCAfMCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTWdoYxX4KN51fP | ||||
| WxQAyGH++VsPbfpAoXIbCPXSmU04BvIxyjzpHQ0ChMKkT/2VNcUeFJwk2fCf+ZwU | ||||
| f0raTQTplofwkckE0gEYA3WcEfJp+hbvbTb/2recsf+JE6JACYJe2Uu5wsjtrE5j | ||||
| A+7aT2BEU9RWzBdSy/5281ZfW3PArqcWaf8+RUyA3WRxVWmjmhFsVB+mdNLhCpW0 | ||||
| C0QNMYR1ppEZiKVnEdao8gcI5sOvSd+35t8g82aPXcNSPU6jKcx1YNUPX5wgPEmu | ||||
| +anfc9RliQbYqqJYVODgBmV8IR5grw93yTsODoWKtFQ4PKVlnt9CD8AS/iSMQYm3 | ||||
| OUogqgMCAwEAAaA/MD0GCSqGSIb3DQEJDjEwMC4wLAYDVR0RBCUwI4IOY2xvdWRm | ||||
| bGFyZS5jb22CEXd3d2Nsb3VkZmxhcmUuY29tMAsGCSqGSIb3DQEBCwOCAQEAl809 | ||||
| gk9uZkRK+MJVYDSLjgGR2xqk5qOwnhovnispA7N3Z1GshodJRQa6ngNCKuXIm2/6 | ||||
| AxB9kDGK14n186Qq4odXqHSHs8FG9i0zUcBXeLv1rPAKtwKTas/SLmsOpPgWPZFa | ||||
| iYiHHeu4HjOQoF987d7uGRYwc3xfstKwJsEXc12eCw2NH8TM1tJgSc/o6CzIpA91 | ||||
| QnZKhx6uGM4xI2gnOaJA1YikNhyFGBuOGMZgd0k2+/IcR2pg0z4pc5oQw1bXLANx | ||||
| anqlA/MDrCM9v9019bRJ73zK8LQ3k/FW61PA9nL7RZ8ku65R+uYcVEdLa8pUeqnH | ||||
| cJZNboDRsItpccZuRQ== | ||||
| -----END NEW CERTIFICATE REQUEST----- | ||||
							
								
								
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/secp256k1-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/secp256k1-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| -----BEGIN EC PRIVATE KEY----- | ||||
| MHQCAQEEIJLKycmoCAk4HqlJGdsuFyHsxfIheKsLH91tS/TNP5OOoAcGBSuBBAAK | ||||
| oUQDQgAEBkmL7cvC2cgchzfSuUZPGnzH0FqBtf3kGhSllQiIzGDn4envPXNqp+93 | ||||
| V2NZ8VT+Aba4ln2Vbp9gYrKquut5Zg== | ||||
| -----END EC PRIVATE KEY----- | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/test.bad.csr.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/test.bad.csr.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIICzDCCAbQCAQAwgYYxCzAJBgNVBAYTAkVOMQ0wCwYDVQQIDARub25lMQ0wCwYD | ||||
| VQQHDARub25lMRIwEAYDVQQKDAlXaWtpcGVkaWExDTALBgNVBAsMBG5vbmUxGDAW | ||||
| BgNVBAMMDyoud2lraXBlZGlhLm9yZzEcMBoGCSqGSIb3DQEJARYNbm9uZUBub25l | ||||
| LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMP/U8RlcCD6E8AL | ||||
| PT8LLUR9ygyygPCaSmIEC8zXGJung3ykElXFRz/Jc/bu0hxCxi2YDz5IjxBBOpB/ | ||||
| kieG83HsSmZZtR+drZIQ6vOsr/ucvpnB9z4XzKuabNGZ5ZiTSQ9L7Mx8FzvUTq5y | ||||
| 57HhA7ECAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4IBAQBn8OCVOIx+n0AS6WbEmYDR | ||||
| SspR9xOCoOwYfamB+2Bpmt82R01zJ/kaqzUtZUjaGvQvAaz5lUwoMdaO0X7I5Xfl | ||||
| sllMFDaYoGD4Rru4s8gz2qG/QHWA8uPXzJVAj6X0olbIdLTEqTKsnBj4Zr1AJCNy | ||||
| /YcG4ouLJr140o26MhwBpoCRpPjAgdYMH60BYfnc4/DILxMVqR9xqK1s98d6Ob/+ | ||||
| 3wHFK+S7BRWrJQXcM8veAexXuk9lHQ+FgGfD0eSYGz0kyP26Qa2pLTwumjt+nBPl | ||||
| rfJxaLHwTQ/1988G0H35ED0f9Md5fzoKi5evU1wG5WRxdEUPyt3QUXxdQ69i0C+7 | ||||
| -----END CERTIFICATE REQUEST----- | ||||
|  | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/test.csr.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/helpers/testdata/test.csr.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIICzDCCAbQCAQAwgYYxCzAJBgNVBAYTAkVOMQ0wCwYDVQQIDARub25lMQ0wCwYD | ||||
| VQQHDARub25lMRIwEAYDVQQKDAlXaWtpcGVkaWExDTALBgNVBAsMBG5vbmUxGDAW | ||||
| BgNVBAMMDyoud2lraXBlZGlhLm9yZzEcMBoGCSqGSIb3DQEJARYNbm9uZUBub25l | ||||
| LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMP/U8RlcCD6E8AL | ||||
| PT8LLUR9ygyygPCaSmIEC8zXGJung3ykElXFRz/Jc/bu0hxCxi2YDz5IjxBBOpB/ | ||||
| kieG83HsSmZZtR+drZIQ6vOsr/ucvpnB9z4XzKuabNGZ5ZiTSQ9L7Mx8FzvUTq5y | ||||
| /ArIuM+FBeuno/IV8zvwAe/VRa8i0QjFXT9vBBp35aeatdnJ2ds50yKCsHHcjvtr | ||||
| 9/8zPVqqmhl2XFS3Qdqlsprzbgksom67OobJGjaV+fNHNQ0o/rzP//Pl3i7vvaEG | ||||
| 7Ff8tQhEwR9nJUR1T6Z7ln7S6cOr23YozgWVkEJ/dSr6LAopb+cZ88FzW5NszU6i | ||||
| 57HhA7ECAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4IBAQBn8OCVOIx+n0AS6WbEmYDR | ||||
| SspR9xOCoOwYfamB+2Bpmt82R01zJ/kaqzUtZUjaGvQvAaz5lUwoMdaO0X7I5Xfl | ||||
| sllMFDaYoGD4Rru4s8gz2qG/QHWA8uPXzJVAj6X0olbIdLTEqTKsnBj4Zr1AJCNy | ||||
| /YcG4ouLJr140o26MhwBpoCRpPjAgdYMH60BYfnc4/DILxMVqR9xqK1s98d6Ob/+ | ||||
| 3wHFK+S7BRWrJQXcM8veAexXuk9lHQ+FgGfD0eSYGz0kyP26Qa2pLTwumjt+nBPl | ||||
| rfJxaLHwTQ/1988G0H35ED0f9Md5fzoKi5evU1wG5WRxdEUPyt3QUXxdQ69i0C+7 | ||||
| -----END CERTIFICATE REQUEST----- | ||||
|  | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/info/info.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/info/info.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| // Package info contains the definitions for the info endpoint | ||||
| package info | ||||
|  | ||||
| // Req is the request struct for an info API request. | ||||
| type Req struct { | ||||
| 	Label   string `json:"label"` | ||||
| 	Profile string `json:"profile"` | ||||
| } | ||||
|  | ||||
| // Resp is the response for an Info API request. | ||||
| type Resp struct { | ||||
| 	Certificate  string   `json:"certificate"` | ||||
| 	Usage        []string `json:"usages"` | ||||
| 	ExpiryString string   `json:"expiry"` | ||||
| } | ||||
							
								
								
									
										249
									
								
								vendor/github.com/cloudflare/cfssl/initca/initca.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								vendor/github.com/cloudflare/cfssl/initca/initca.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,249 @@ | ||||
| // Package initca contains code to initialise a certificate authority, | ||||
| // generating a new root key and certificate. | ||||
| package initca | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/config" | ||||
| 	"github.com/cloudflare/cfssl/csr" | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| 	"github.com/cloudflare/cfssl/log" | ||||
| 	"github.com/cloudflare/cfssl/signer" | ||||
| 	"github.com/cloudflare/cfssl/signer/local" | ||||
| ) | ||||
|  | ||||
| // validator contains the default validation logic for certificate | ||||
| // authority certificates. The only requirement here is that the | ||||
| // certificate have a non-empty subject field. | ||||
| func validator(req *csr.CertificateRequest) error { | ||||
| 	if req.CN != "" { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if len(req.Names) == 0 { | ||||
| 		return cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("missing subject information")) | ||||
| 	} | ||||
|  | ||||
| 	for i := range req.Names { | ||||
| 		if csr.IsNameEmpty(req.Names[i]) { | ||||
| 			return cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("missing subject information")) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // New creates a new root certificate from the certificate request. | ||||
| func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { | ||||
| 	policy := CAPolicy() | ||||
| 	if req.CA != nil { | ||||
| 		if req.CA.Expiry != "" { | ||||
| 			policy.Default.ExpiryString = req.CA.Expiry | ||||
| 			policy.Default.Expiry, err = time.ParseDuration(req.CA.Expiry) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if req.CA.Backdate != "" { | ||||
| 			policy.Default.Backdate, err = time.ParseDuration(req.CA.Backdate) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		policy.Default.CAConstraint.MaxPathLen = req.CA.PathLength | ||||
| 		if req.CA.PathLength != 0 && req.CA.PathLenZero { | ||||
| 			log.Infof("ignore invalid 'pathlenzero' value") | ||||
| 		} else { | ||||
| 			policy.Default.CAConstraint.MaxPathLenZero = req.CA.PathLenZero | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	g := &csr.Generator{Validator: validator} | ||||
| 	csrPEM, key, err = g.ProcessRequest(req) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to process request: %v", err) | ||||
| 		key = nil | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEM(key) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to parse private key: %v", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), policy) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to create signer: %v", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	signReq := signer.SignRequest{Hosts: req.Hosts, Request: string(csrPEM)} | ||||
| 	cert, err = s.Sign(signReq) | ||||
|  | ||||
| 	return | ||||
|  | ||||
| } | ||||
|  | ||||
| // NewFromPEM creates a new root certificate from the key file passed in. | ||||
| func NewFromPEM(req *csr.CertificateRequest, keyFile string) (cert, csrPEM []byte, err error) { | ||||
| 	privData, err := helpers.ReadBytes(keyFile) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEM(privData) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | ||||
| 	return NewFromSigner(req, priv) | ||||
| } | ||||
|  | ||||
| // RenewFromPEM re-creates a root certificate from the CA cert and key | ||||
| // files. The resulting root certificate will have the input CA certificate | ||||
| // as the template and have the same expiry length. E.g. the existing CA | ||||
| // is valid for a year from Jan 01 2015 to Jan 01 2016, the renewed certificate | ||||
| // will be valid from now and expire in one year as well. | ||||
| func RenewFromPEM(caFile, keyFile string) ([]byte, error) { | ||||
| 	caBytes, err := helpers.ReadBytes(caFile) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ca, err := helpers.ParseCertificatePEM(caBytes) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	keyBytes, err := helpers.ReadBytes(keyFile) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	key, err := helpers.ParsePrivateKeyPEM(keyBytes) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return RenewFromSigner(ca, key) | ||||
| } | ||||
|  | ||||
| // NewFromSigner creates a new root certificate from a crypto.Signer. | ||||
| func NewFromSigner(req *csr.CertificateRequest, priv crypto.Signer) (cert, csrPEM []byte, err error) { | ||||
| 	policy := CAPolicy() | ||||
| 	if req.CA != nil { | ||||
| 		if req.CA.Expiry != "" { | ||||
| 			policy.Default.ExpiryString = req.CA.Expiry | ||||
| 			policy.Default.Expiry, err = time.ParseDuration(req.CA.Expiry) | ||||
| 			if err != nil { | ||||
| 				return nil, nil, err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		policy.Default.CAConstraint.MaxPathLen = req.CA.PathLength | ||||
| 		if req.CA.PathLength != 0 && req.CA.PathLenZero == true { | ||||
| 			log.Infof("ignore invalid 'pathlenzero' value") | ||||
| 		} else { | ||||
| 			policy.Default.CAConstraint.MaxPathLenZero = req.CA.PathLenZero | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	csrPEM, err = csr.Generate(priv, req) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | ||||
| 	s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), policy) | ||||
| 	if err != nil { | ||||
| 		log.Errorf("failed to create signer: %v", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	signReq := signer.SignRequest{Request: string(csrPEM)} | ||||
| 	cert, err = s.Sign(signReq) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // RenewFromSigner re-creates a root certificate from the CA cert and crypto.Signer. | ||||
| // The resulting root certificate will have ca certificate | ||||
| // as the template and have the same expiry length. E.g. the existing CA | ||||
| // is valid for a year from Jan 01 2015 to Jan 01 2016, the renewed certificate | ||||
| // will be valid from now and expire in one year as well. | ||||
| func RenewFromSigner(ca *x509.Certificate, priv crypto.Signer) ([]byte, error) { | ||||
| 	if !ca.IsCA { | ||||
| 		return nil, errors.New("input certificate is not a CA cert") | ||||
| 	} | ||||
|  | ||||
| 	// matching certificate public key vs private key | ||||
| 	switch { | ||||
| 	case ca.PublicKeyAlgorithm == x509.RSA: | ||||
| 		var rsaPublicKey *rsa.PublicKey | ||||
| 		var ok bool | ||||
| 		if rsaPublicKey, ok = priv.Public().(*rsa.PublicKey); !ok { | ||||
| 			return nil, cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch) | ||||
| 		} | ||||
| 		if ca.PublicKey.(*rsa.PublicKey).N.Cmp(rsaPublicKey.N) != 0 { | ||||
| 			return nil, cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch) | ||||
| 		} | ||||
| 	case ca.PublicKeyAlgorithm == x509.ECDSA: | ||||
| 		var ecdsaPublicKey *ecdsa.PublicKey | ||||
| 		var ok bool | ||||
| 		if ecdsaPublicKey, ok = priv.Public().(*ecdsa.PublicKey); !ok { | ||||
| 			return nil, cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch) | ||||
| 		} | ||||
| 		if ca.PublicKey.(*ecdsa.PublicKey).X.Cmp(ecdsaPublicKey.X) != 0 { | ||||
| 			return nil, cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch) | ||||
| 		} | ||||
| 	default: | ||||
| 		return nil, cferr.New(cferr.PrivateKeyError, cferr.NotRSAOrECC) | ||||
| 	} | ||||
|  | ||||
| 	req := csr.ExtractCertificateRequest(ca) | ||||
| 	cert, _, err := NewFromSigner(req, priv) | ||||
| 	return cert, err | ||||
|  | ||||
| } | ||||
|  | ||||
| // CAPolicy contains the CA issuing policy as default policy. | ||||
| var CAPolicy = func() *config.Signing { | ||||
| 	return &config.Signing{ | ||||
| 		Default: &config.SigningProfile{ | ||||
| 			Usage:        []string{"cert sign", "crl sign"}, | ||||
| 			ExpiryString: "43800h", | ||||
| 			Expiry:       5 * helpers.OneYear, | ||||
| 			CAConstraint: config.CAConstraint{IsCA: true}, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Update copies the CA certificate, updates the NotBefore and | ||||
| // NotAfter fields, and then re-signs the certificate. | ||||
| func Update(ca *x509.Certificate, priv crypto.Signer) (cert []byte, err error) { | ||||
| 	copy, err := x509.ParseCertificate(ca.Raw) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	validity := ca.NotAfter.Sub(ca.NotBefore) | ||||
| 	copy.NotBefore = time.Now().Round(time.Minute).Add(-5 * time.Minute) | ||||
| 	copy.NotAfter = copy.NotBefore.Add(validity) | ||||
| 	cert, err = x509.CreateCertificate(rand.Reader, copy, copy, priv.Public(), priv) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert}) | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										385
									
								
								vendor/github.com/cloudflare/cfssl/initca/initca_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								vendor/github.com/cloudflare/cfssl/initca/initca_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,385 @@ | ||||
| package initca | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/rsa" | ||||
| 	"io/ioutil" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/config" | ||||
| 	"github.com/cloudflare/cfssl/csr" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| 	"github.com/cloudflare/cfssl/signer" | ||||
| 	"github.com/cloudflare/cfssl/signer/local" | ||||
| ) | ||||
|  | ||||
| var validKeyParams = []csr.BasicKeyRequest{ | ||||
| 	{A: "rsa", S: 2048}, | ||||
| 	{A: "rsa", S: 3072}, | ||||
| 	{A: "rsa", S: 4096}, | ||||
| 	{A: "ecdsa", S: 256}, | ||||
| 	{A: "ecdsa", S: 384}, | ||||
| 	{A: "ecdsa", S: 521}, | ||||
| } | ||||
|  | ||||
| var validCAConfigs = []csr.CAConfig{ | ||||
| 	{PathLength: 0, PathLenZero: true}, | ||||
| 	{PathLength: 0, PathLenZero: false}, | ||||
| 	{PathLength: 2}, | ||||
| 	{PathLength: 2, Expiry: "1h"}, | ||||
| 	// invalid PathLenZero value will be ignored | ||||
| 	{PathLength: 2, PathLenZero: true}, | ||||
| } | ||||
|  | ||||
| var invalidCAConfig = csr.CAConfig{ | ||||
| 	PathLength: 2, | ||||
| 	// Expiry must be a duration string | ||||
| 	Expiry: "2116/12/31", | ||||
| } | ||||
| var csrFiles = []string{ | ||||
| 	"testdata/rsa2048.csr", | ||||
| 	"testdata/rsa3072.csr", | ||||
| 	"testdata/rsa4096.csr", | ||||
| 	"testdata/ecdsa256.csr", | ||||
| 	"testdata/ecdsa384.csr", | ||||
| 	"testdata/ecdsa521.csr", | ||||
| } | ||||
|  | ||||
| var testRSACAFile = "testdata/5min-rsa.pem" | ||||
| var testRSACAKeyFile = "testdata/5min-rsa-key.pem" | ||||
| var testECDSACAFile = "testdata/5min-ecdsa.pem" | ||||
| var testECDSACAKeyFile = "testdata/5min-ecdsa-key.pem" | ||||
|  | ||||
| var invalidCryptoParams = []csr.BasicKeyRequest{ | ||||
| 	// Weak Key | ||||
| 	{A: "rsa", S: 1024}, | ||||
| 	// Bad param | ||||
| 	{A: "rsaCrypto", S: 2048}, | ||||
| 	{A: "ecdsa", S: 2000}, | ||||
| } | ||||
|  | ||||
| func TestInitCA(t *testing.T) { | ||||
| 	var req *csr.CertificateRequest | ||||
| 	hostname := "cloudflare.com" | ||||
| 	for _, param := range validKeyParams { | ||||
| 		for _, caconfig := range validCAConfigs { | ||||
| 			req = &csr.CertificateRequest{ | ||||
| 				Names: []csr.Name{ | ||||
| 					{ | ||||
| 						C:  "US", | ||||
| 						ST: "California", | ||||
| 						L:  "San Francisco", | ||||
| 						O:  "CloudFlare", | ||||
| 						OU: "Systems Engineering", | ||||
| 					}, | ||||
| 				}, | ||||
| 				CN:         hostname, | ||||
| 				Hosts:      []string{hostname, "www." + hostname}, | ||||
| 				KeyRequest: ¶m, | ||||
| 				CA:         &caconfig, | ||||
| 			} | ||||
| 			certBytes, _, keyBytes, err := New(req) | ||||
| 			if err != nil { | ||||
| 				t.Fatal("InitCA failed:", err) | ||||
| 			} | ||||
| 			key, err := helpers.ParsePrivateKeyPEM(keyBytes) | ||||
| 			if err != nil { | ||||
| 				t.Fatal("InitCA private key parsing failed:", err) | ||||
| 			} | ||||
| 			cert, err := helpers.ParseCertificatePEM(certBytes) | ||||
| 			if err != nil { | ||||
| 				t.Fatal("InitCA cert parsing failed:", err) | ||||
| 			} | ||||
|  | ||||
| 			// Verify key parameters. | ||||
| 			switch req.KeyRequest.Algo() { | ||||
| 			case "rsa": | ||||
| 				if cert.PublicKey.(*rsa.PublicKey).N.BitLen() != param.Size() { | ||||
| 					t.Fatal("Cert key length mismatch.") | ||||
| 				} | ||||
| 				if key.(*rsa.PrivateKey).N.BitLen() != param.Size() { | ||||
| 					t.Fatal("Private key length mismatch.") | ||||
| 				} | ||||
| 			case "ecdsa": | ||||
| 				if cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().BitSize != param.Size() { | ||||
| 					t.Fatal("Cert key length mismatch.") | ||||
| 				} | ||||
| 				if key.(*ecdsa.PrivateKey).Curve.Params().BitSize != param.Size() { | ||||
| 					t.Fatal("Private key length mismatch.") | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// Verify CA MaxPathLen | ||||
| 			if caconfig.PathLength == 0 && cert.MaxPathLenZero != caconfig.PathLenZero { | ||||
| 				t.Fatalf("fail to init a CA cert with specified CA pathlen zero: expect %v, got %v", caconfig.PathLenZero, cert.MaxPathLenZero) | ||||
| 			} | ||||
|  | ||||
| 			if caconfig.PathLength != 0 { | ||||
| 				if cert.MaxPathLen != caconfig.PathLength { | ||||
| 					t.Fatalf("fail to init a CA cert with specified CA pathlen: expect %d, got %d", caconfig.PathLength, cert.MaxPathLen) | ||||
| 				} | ||||
| 				if cert.MaxPathLenZero != false { | ||||
| 					t.Fatalf("fail to init a CA cert with specified CA pathlen zero: expect false, got %t", cert.MaxPathLenZero) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// Replace the default CAPolicy with a test (short expiry) version. | ||||
| 			CAPolicy = func() *config.Signing { | ||||
| 				return &config.Signing{ | ||||
| 					Default: &config.SigningProfile{ | ||||
| 						Usage:        []string{"cert sign", "crl sign"}, | ||||
| 						ExpiryString: "300s", | ||||
| 						Expiry:       300 * time.Second, | ||||
| 						CAConstraint: config.CAConstraint{IsCA: true}, | ||||
| 					}, | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// Start a signer | ||||
| 			s, err := local.NewSigner(key, cert, signer.DefaultSigAlgo(key), nil) | ||||
| 			if err != nil { | ||||
| 				t.Fatal("Signer Creation error:", err) | ||||
| 			} | ||||
| 			s.SetPolicy(CAPolicy()) | ||||
|  | ||||
| 			// Sign RSA and ECDSA customer CSRs. | ||||
| 			for _, csrFile := range csrFiles { | ||||
| 				csrBytes, err := ioutil.ReadFile(csrFile) | ||||
| 				if err != nil { | ||||
| 					t.Fatal("CSR loading error:", err) | ||||
| 				} | ||||
| 				req := signer.SignRequest{ | ||||
| 					Request: string(csrBytes), | ||||
| 					Hosts:   signer.SplitHosts(hostname), | ||||
| 					Profile: "", | ||||
| 					Label:   "", | ||||
| 				} | ||||
|  | ||||
| 				bytes, err := s.Sign(req) | ||||
| 				if err != nil { | ||||
| 					t.Fatal(err) | ||||
| 				} | ||||
| 				customerCert, _ := helpers.ParseCertificatePEM(bytes) | ||||
| 				if customerCert.SignatureAlgorithm != s.SigAlgo() { | ||||
| 					t.Fatal("Signature Algorithm mismatch") | ||||
| 				} | ||||
| 				err = customerCert.CheckSignatureFrom(cert) | ||||
| 				if err != nil { | ||||
| 					t.Fatal("Signing CSR failed.", err) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| func TestInvalidCAConfig(t *testing.T) { | ||||
| 	hostname := "example.com" | ||||
| 	req := &csr.CertificateRequest{ | ||||
| 		Names: []csr.Name{ | ||||
| 			{ | ||||
| 				C:  "US", | ||||
| 				ST: "California", | ||||
| 				L:  "San Francisco", | ||||
| 				O:  "CloudFlare", | ||||
| 				OU: "Systems Engineering", | ||||
| 			}, | ||||
| 		}, | ||||
| 		CN:         hostname, | ||||
| 		Hosts:      []string{hostname, "www." + hostname}, | ||||
| 		KeyRequest: &validKeyParams[0], | ||||
| 		CA:         &invalidCAConfig, | ||||
| 	} | ||||
|  | ||||
| 	_, _, _, err := New(req) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("InitCA with bad CAConfig should fail:", err) | ||||
| 	} | ||||
| } | ||||
| func TestInvalidCryptoParams(t *testing.T) { | ||||
| 	var req *csr.CertificateRequest | ||||
| 	hostname := "cloudflare.com" | ||||
| 	for _, invalidParam := range invalidCryptoParams { | ||||
| 		req = &csr.CertificateRequest{ | ||||
| 			Names: []csr.Name{ | ||||
| 				{ | ||||
| 					C:  "US", | ||||
| 					ST: "California", | ||||
| 					L:  "San Francisco", | ||||
| 					O:  "CloudFlare", | ||||
| 					OU: "Systems Engineering", | ||||
| 				}, | ||||
| 			}, | ||||
| 			CN:         hostname, | ||||
| 			Hosts:      []string{hostname, "www." + hostname}, | ||||
| 			KeyRequest: &invalidParam, | ||||
| 		} | ||||
| 		_, _, _, err := New(req) | ||||
| 		if err == nil { | ||||
| 			t.Fatal("InitCA with bad params should fail:", err) | ||||
| 		} | ||||
|  | ||||
| 		if !strings.Contains(err.Error(), `"code":2400`) { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type validation struct { | ||||
| 	r *csr.CertificateRequest | ||||
| 	v bool | ||||
| } | ||||
|  | ||||
| var testValidations = []validation{ | ||||
| 	{&csr.CertificateRequest{}, false}, | ||||
| 	{&csr.CertificateRequest{ | ||||
| 		CN: "test CA", | ||||
| 	}, true}, | ||||
| 	{&csr.CertificateRequest{ | ||||
| 		Names: []csr.Name{{}}, | ||||
| 	}, false}, | ||||
| 	{&csr.CertificateRequest{ | ||||
| 		Names: []csr.Name{ | ||||
| 			{O: "Example CA"}, | ||||
| 		}, | ||||
| 	}, true}, | ||||
| } | ||||
|  | ||||
| func TestValidations(t *testing.T) { | ||||
| 	for i, tv := range testValidations { | ||||
| 		err := validator(tv.r) | ||||
| 		if tv.v && err != nil { | ||||
| 			t.Fatalf("%v", err) | ||||
| 		} | ||||
|  | ||||
| 		if !tv.v && err == nil { | ||||
| 			t.Fatalf("%d: expected error, but no error was reported", i) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRenewRSA(t *testing.T) { | ||||
| 	certPEM, err := RenewFromPEM(testRSACAFile, testRSACAKeyFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// must parse ok | ||||
| 	cert, err := helpers.ParseCertificatePEM(certPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if !cert.IsCA { | ||||
| 		t.Fatal("renewed CA certificate is not CA") | ||||
| 	} | ||||
|  | ||||
| 	// cert expiry must be 5 minutes | ||||
| 	expiry := cert.NotAfter.Sub(cert.NotBefore).Seconds() | ||||
| 	if expiry >= 301 || expiry <= 299 { | ||||
| 		t.Fatal("expiry is not correct:", expiry) | ||||
| 	} | ||||
|  | ||||
| 	// check subject | ||||
|  | ||||
| 	if cert.Subject.CommonName != "" { | ||||
| 		t.Fatal("Bad CommonName") | ||||
| 	} | ||||
|  | ||||
| 	if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "US" { | ||||
| 		t.Fatal("Bad Subject") | ||||
| 	} | ||||
|  | ||||
| 	if len(cert.Subject.Organization) != 1 || cert.Subject.Organization[0] != "CloudFlare, Inc." { | ||||
| 		t.Fatal("Bad Subject") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRenewECDSA(t *testing.T) { | ||||
| 	certPEM, err := RenewFromPEM(testECDSACAFile, testECDSACAKeyFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// must parse ok | ||||
| 	cert, err := helpers.ParseCertificatePEM(certPEM) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if !cert.IsCA { | ||||
| 		t.Fatal("renewed CA certificate is not CA") | ||||
| 	} | ||||
|  | ||||
| 	// cert expiry must be 5 minutes | ||||
| 	expiry := cert.NotAfter.Sub(cert.NotBefore).Seconds() | ||||
| 	if expiry >= 301 || expiry <= 299 { | ||||
| 		t.Fatal("expiry is not correct:", expiry) | ||||
| 	} | ||||
|  | ||||
| 	// check subject | ||||
|  | ||||
| 	if cert.Subject.CommonName != "" { | ||||
| 		t.Fatal("Bad CommonName") | ||||
| 	} | ||||
|  | ||||
| 	if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "US" { | ||||
| 		t.Fatal("Bad Subject") | ||||
| 	} | ||||
|  | ||||
| 	if len(cert.Subject.Organization) != 1 || cert.Subject.Organization[0] != "CloudFlare, Inc." { | ||||
| 		t.Fatal("Bad Subject") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRenewMismatch(t *testing.T) { | ||||
| 	_, err := RenewFromPEM(testECDSACAFile, testRSACAKeyFile) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Fail to detect cert/key mismatch") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRenew(t *testing.T) { | ||||
| 	in, err := ioutil.ReadFile(testECDSACAFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	cert, err := helpers.ParseCertificatePEM(in) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	in, err = ioutil.ReadFile(testECDSACAKeyFile) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEM(in) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	renewed, err := Update(cert, priv) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	newCert, err := helpers.ParseCertificatePEM(renewed) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if !bytes.Equal(newCert.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) { | ||||
| 		t.Fatal("Update returned a certificate with different subject public key info") | ||||
| 	} | ||||
|  | ||||
| 	if !bytes.Equal(newCert.RawSubject, cert.RawSubject) { | ||||
| 		t.Fatal("Update returned a certificate with different subject info") | ||||
| 	} | ||||
|  | ||||
| 	if !bytes.Equal(newCert.RawIssuer, cert.RawIssuer) { | ||||
| 		t.Fatal("Update returned a certificate with different issuer info") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-ecdsa-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-ecdsa-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| -----BEGIN EC PRIVATE KEY----- | ||||
| MHcCAQEEIA8OzPeVZT0cXTAPdcXYefLRIqyUXa0f0SgYMJ2J1AVcoAoGCCqGSM49 | ||||
| AwEHoUQDQgAEoCV+bVOLTJMy38j50sc3vE5k41GMRgriFJt0g0OVX8yaOZ93CZTI | ||||
| 7LzfGbMU+KqWTgOwGhrPvpusep3fjw+dAQ== | ||||
| -----END EC PRIVATE KEY----- | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-ecdsa.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-ecdsa.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIICUDCCAfagAwIBAgIIec5PjdpJcNYwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMC | ||||
| VVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAhBgNVBAsTGlRlc3QgQ2Vy | ||||
| dGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYD | ||||
| VQQIEwpDYWxpZm9ybmlhMB4XDTE1MTAwODIzMDEwMFoXDTE1MTAwODIzMDYwMFow | ||||
| ejELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAhBgNV | ||||
| BAsTGlRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMFkwEwYHKoZIzj0CAQYIKoZIzj0D | ||||
| AQcDQgAEoCV+bVOLTJMy38j50sc3vE5k41GMRgriFJt0g0OVX8yaOZ93CZTI7Lzf | ||||
| GbMU+KqWTgOwGhrPvpusep3fjw+dAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1Ud | ||||
| EwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFDpLhSKBN3njfb6cXQCdRLzCZt0ZMB8G | ||||
| A1UdIwQYMBaAFDpLhSKBN3njfb6cXQCdRLzCZt0ZMAoGCCqGSM49BAMCA0gAMEUC | ||||
| IFU3BmzntGGeXZu2qWZx249nYn37S0AkCnQ3rUtI31bdAiEAsPICnZ+GB8yCN26N | ||||
| OL+N8dHvXiOvZ9/Vl488pyWOccY= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-rsa-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-rsa-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| MIIEogIBAAKCAQEAtrYWs9ao2CpLWWLMyJJr3Bw7eJu3vSImzoqsBuhAREMaeuHm | ||||
| vAwqbByVpdxu1o+t0u6cMp/1M4YwDSxD4Ny3zEUUGse6yZpyph0+whdHSn1LOCxY | ||||
| KVwMtcYaEswenm0a+s/b9BYpbLv6lPoJ8+6bQNDuyyracDzlvGgk/HabemqDly4+ | ||||
| W64tlrMUDHBuHHIm5EMF1sqVcinLCS8KsVDVfg4qKfzsZbTw0dDo5GZh1lPslkk9 | ||||
| y8NzRltZjfJ3y5acv7SvIlETpy41VxScplR+Ot/6sXNJY3aEBT10smPXPABDeWjx | ||||
| FbnU5xacL/pC7pnKy734sL4lkvzKPDWZPsNMEwIDAQABAoIBAHIFHBHKib+sVS1I | ||||
| 7MbWKR1JOQvBEV6kK1eFTmlZEpIG1kWNJ/J+HRMum2zQLRMUwsL5SNyG2fv3Z5Ew | ||||
| 6IMw+joteahkr/oTuixT39A7uq+PlRtPAQ1+digRoj/MxebT65xNjtO56MwEWxIR | ||||
| H5jsdFJ0kDCVY4/bUPrMexhZ5Bj1xM3j8wpCPlVv2b9Ic/FUD9p6tOZDFhfSluiE | ||||
| 87VsFHUImNvu4p/BAKUuKiz58cPNDHPAABsPrJR2SVU59roC4QtEmaxbmDkXUtB1 | ||||
| +o+ypJQ0saqoffzHq7URebrJU9u+AV51UWaqHjg5OAe8eElOou6MHYX8R9cWZmJX | ||||
| UQKPyVECgYEAyLqstNHtA7R7+r4bW8Tr/kF7z+VvCfV9wB6TPT+ycuv3aU5+HYgR | ||||
| YRs2RBRtwI625hPk7AXEdbMt3SKoKjcMNMSD3qUK+fJFEyvOqRXiMJ2pLg04GlYZ | ||||
| cOInJd0T1q3O2cNLZwcWB1L0/KiV0dYHc4p+p5hisai3T9w7QthTUr8CgYEA6QVW | ||||
| jcsSBRFCokf/GKpTCVXIeqDSwrcEwoZh/RN6PlvgDwjw08G2IxKdAFs3/wxbKWHT | ||||
| xss+LQiMyBL8aRJvBUfotj5e5ZYESaSDqdeYv0Sydl1vfxcknHpTBRUdbyDtsOQn | ||||
| 4X1ZEmfa9vFWS5P9fTFBC0BU2zzrhSlfQb6g360CgYBmnT+zBGo07aw/p7XWuRmn | ||||
| lhRUWEbmgXAyqa69rfVs2IJXfD/umuO/j6izLvpYaNzJS7xIiD5BqUK1/ISZaCC+ | ||||
| TQPY6uhslFSJk2iHed9y2PZmy2010XQaCBLZQWZl5d6L5lGCrtWtEtSY4RoN9mtC | ||||
| vrc2uCkkB0sG8V/+MRaPgwKBgBiML2oQkn1mLBbcbssyZjz9hHkmqA1LKn0zmu8G | ||||
| NkKLezcaQgSMy5s2QsPe2C9OJexeGek/T/V+iRYqqdyHzJpJ0QIh3+1fuGPpqNUj | ||||
| mTvNCN/fR/ejgH/bgxNt/gPO/Ds+TdU7Vz7RIggRtH2RwYqGvctpo4bVDBqjGR3b | ||||
| 7yahAoGAAgH97uN2FU1ffK0OAfMA1N58ikq/bg07KnJxO2CP5hrgsWK2ZVfeHUmU | ||||
| 3k+xqQHCIuew55yO0tARTrFAh3Rj+zarA+PrtnzqW82wCIn8Fym3PFzbK2qrIMie | ||||
| yp0p4nBXsRmzinrPWKUYlFyRNY3Tcbstm5gUw2S4czSwwQeM/No= | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-rsa.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/5min-rsa.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIID3DCCAsSgAwIBAgIIfbm2I1hwBa8wDQYJKoZIhvcNAQELBQAwejELMAkGA1UE | ||||
| BhMCVVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAhBgNVBAsTGlRlc3Qg | ||||
| Q2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMw | ||||
| EQYDVQQIEwpDYWxpZm9ybmlhMB4XDTE1MTAwODIwMjEwMFoXDTE1MTAwODIwMjYw | ||||
| MFowejELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIzAh | ||||
| BgNVBAsTGlRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4g | ||||
| RnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMIIBIjANBgkqhkiG9w0BAQEF | ||||
| AAOCAQ8AMIIBCgKCAQEAtrYWs9ao2CpLWWLMyJJr3Bw7eJu3vSImzoqsBuhAREMa | ||||
| euHmvAwqbByVpdxu1o+t0u6cMp/1M4YwDSxD4Ny3zEUUGse6yZpyph0+whdHSn1L | ||||
| OCxYKVwMtcYaEswenm0a+s/b9BYpbLv6lPoJ8+6bQNDuyyracDzlvGgk/HabemqD | ||||
| ly4+W64tlrMUDHBuHHIm5EMF1sqVcinLCS8KsVDVfg4qKfzsZbTw0dDo5GZh1lPs | ||||
| lkk9y8NzRltZjfJ3y5acv7SvIlETpy41VxScplR+Ot/6sXNJY3aEBT10smPXPABD | ||||
| eWjxFbnU5xacL/pC7pnKy734sL4lkvzKPDWZPsNMEwIDAQABo2YwZDAOBgNVHQ8B | ||||
| Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUCHoGEI1RZ8JN | ||||
| 7UZ4zcTRll8nnnAwHwYDVR0jBBgwFoAUCHoGEI1RZ8JN7UZ4zcTRll8nnnAwDQYJ | ||||
| KoZIhvcNAQELBQADggEBAHRcbd6cSXV6IuT4jLV8k6OUUlxzobbiRnXJrLjy9Anx | ||||
| tyIUWv2XSh/4IEJa+/MLNIb28gU9Sa2y4GV1qAgOM5qUM2iQJyLem0pTg0WTVKlj | ||||
| ytEK1kUwQCNkc/xpDrPo5CbN3aDuW/VPntOJL1GSQzS7jzK3NeQ9sah9YYhk4Wsk | ||||
| jzHVI1sX+qzcuUqCIPhqmGR0JE8ZI5YzbMTZ4/B+oWxZ7EyzB8O+v6HVD4eQFBSq | ||||
| tyGhGbh7mUvuMpVJ8FIX4BA7QL+RwqNNtAMZKcxPjhy5I23nVclbTCz/NC2Dgp8H | ||||
| 13uQsEpUZ65clgiTo4LuPzPiIouZh5cBWP4gGqbyyS4= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| 1. To generate 5min-rsa.pem and 5min-rsa-key.pem | ||||
| ``` | ||||
| $ GOPATH/bin/cfssl gencert -initca ca_csr_rsa.json | GOPATH/bin/cfssljson -bare 5min-rsa | ||||
| ``` | ||||
| 2. To generate 5min-ecdsa.pem and 5min-ecdsa-key.pem | ||||
| ``` | ||||
| $ GOPATH/bin/cfssl gencert -initca ca_csr_ecdsa.json | GOPATH/bin/cfssljson -bare 5min-ecdsa | ||||
| ``` | ||||
|  | ||||
| The above commands will generate 5min-rsa.csr and 5min-ecdsa.csr as well, but those | ||||
| files can be ignored. | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ca_csr_ecdsa.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ca_csr_ecdsa.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| { | ||||
|   "key": { | ||||
|     "algo": "ecdsa", | ||||
|     "size": 256 | ||||
|   }, | ||||
|   "names": [ | ||||
|     { | ||||
|     "C": "US", | ||||
|     "L": "San Francisco", | ||||
|     "ST": "California", | ||||
|     "O": "CloudFlare, Inc.", | ||||
|     "OU": "Test Certificate Authority" | ||||
|     } | ||||
|   ], | ||||
|   "ca": { | ||||
|     "expiry": "5m" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ca_csr_rsa.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ca_csr_rsa.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| { | ||||
|   "key": { | ||||
|     "algo": "rsa", | ||||
|     "size": 2048 | ||||
|   }, | ||||
|   "names": [ | ||||
|     { | ||||
|     "C": "US", | ||||
|     "L": "San Francisco", | ||||
|     "ST": "California", | ||||
|     "O": "CloudFlare, Inc.", | ||||
|     "OU": "Test Certificate Authority" | ||||
|     } | ||||
|   ], | ||||
|   "ca": { | ||||
|     "expiry": "5m" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa256.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa256.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIBgTCCASgCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBn9Ldie6BOcMHezn2dPuYqW | ||||
| z/NoLYMLGNBqhOxUyEidYClI0JW2pWyUgT3A2UazFp1WgE94y7Z+2YlfRz+vcrKg | ||||
| PzA9BgkqhkiG9w0BCQ4xMDAuMCwGA1UdEQQlMCOCDmNsb3VkZmxhcmUuY29tghF3 | ||||
| d3djbG91ZGZsYXJlLmNvbTAKBggqhkjOPQQDAgNHADBEAiBM+QRxe8u6rkdr10Jy | ||||
| cxbR6NxrGrNeg5QqiOqF96JEmgIgDbtjd5e3y3I8W/+ih2us3WtMxgnTXfqPd48i | ||||
| VLcv28Q= | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										12
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa384.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa384.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIBvzCCAUUCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTB2MBAGByqGSM49AgEGBSuBBAAiA2IABBk/Q+zMsZOJGkufRzGCWtSUtRjq | ||||
| 0QqChDGWbHLaa0h6ODVeEoKYOMvFJTg4V186tuuBe97KEey0OPDegzCBp5kBIiwg | ||||
| HB/0xWoKdnfdRk6VyjmubPx399cGoZn8aCqgC6A/MD0GCSqGSIb3DQEJDjEwMC4w | ||||
| LAYDVR0RBCUwI4IOY2xvdWRmbGFyZS5jb22CEXd3d2Nsb3VkZmxhcmUuY29tMAoG | ||||
| CCqGSM49BAMDA2gAMGUCMQC57VfwMXDyL5kM7vmO2ynbpgSAuFZT6Yd3C3NnV2jz | ||||
| Biozw3eqIDXqCb2LI09stZMCMGIwCuVARr2IRctxf7AmX7/O2SIaIhCpMFKRedQ7 | ||||
| RiWGZIucp5r6AfT9381PB29bHA== | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa521.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/ecdsa521.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIICCjCCAWsCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAHt/s9KTZETzu94JIAjZ3BaS | ||||
| toSG65hGIc1e0Gt7PhdQxPp5FP2D8rQ1wc+pcZhD2O8525kPxopaqTd+fWKBuD3O | ||||
| AULzoH2OX+atIuumTQzLNbTsIbP0tY3dh7d8LItuERkZn1NfsNl3z6bnNAaR137m | ||||
| f4aWv49ImbA/Tkv8VmoKX279oD8wPQYJKoZIhvcNAQkOMTAwLjAsBgNVHREEJTAj | ||||
| gg5jbG91ZGZsYXJlLmNvbYIRd3d3Y2xvdWRmbGFyZS5jb20wCgYIKoZIzj0EAwQD | ||||
| gYwAMIGIAkIA8OX9LxWOVnyfB25DFBz6JkjhyDpBM/PXlgLnWb/n2mEuMMB44DOG | ||||
| pljDV768PSW11AC3DtULoIyR92z0TyLEKYoCQgHdGd6PwUtDW5mrAMJQDgebjsxu | ||||
| MwfcdthzKlFlSmRpHMBnRMOJjlg5f9CTBg9d6wEdv7ZIrQSO6eqQHDQRM0VMnw== | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa2048.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa2048.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIDCTCCAfMCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTWdoYxX4KN51fP | ||||
| WxQAyGH++VsPbfpAoXIbCPXSmU04BvIxyjzpHQ0ChMKkT/2VNcUeFJwk2fCf+ZwU | ||||
| f0raTQTplofwkckE0gEYA3WcEfJp+hbvbTb/2recsf+JE6JACYJe2Uu5wsjtrE5j | ||||
| A+7aT2BEU9RWzBdSy/5281ZfW3PArqcWaf8+RUyA3WRxVWmjmhFsVB+mdNLhCpW0 | ||||
| C0QNMYR1ppEZiKVnEdao8gcI5sOvSd+35t8g82aPXcNSPU6jKcx1YNUPX5wgPEmu | ||||
| +anfc9RliQbYqqJYVODgBmV8IR5grw93yTsODoWKtFQ4PKVlnt9CD8AS/iSMQYm3 | ||||
| OUogqgMCAwEAAaA/MD0GCSqGSIb3DQEJDjEwMC4wLAYDVR0RBCUwI4IOY2xvdWRm | ||||
| bGFyZS5jb22CEXd3d2Nsb3VkZmxhcmUuY29tMAsGCSqGSIb3DQEBCwOCAQEAl809 | ||||
| gk9uZkRK+MJVYDSLjgGR2xqk5qOwnhovnispA7N3Z1GshodJRQa6ngNCKuXIm2/6 | ||||
| AxB9kDGK14n186Qq4odXqHSHs8FG9i0zUcBXeLv1rPAKtwKTas/SLmsOpPgWPZFa | ||||
| iYiHHeu4HjOQoF987d7uGRYwc3xfstKwJsEXc12eCw2NH8TM1tJgSc/o6CzIpA91 | ||||
| QnZKhx6uGM4xI2gnOaJA1YikNhyFGBuOGMZgd0k2+/IcR2pg0z4pc5oQw1bXLANx | ||||
| anqlA/MDrCM9v9019bRJ73zK8LQ3k/FW61PA9nL7RZ8ku65R+uYcVEdLa8pUeqnH | ||||
| cJZNboDRsItpccZuRQ== | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa3072.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa3072.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIECTCCAnMCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAL0zzgBv+VTwZOPy | ||||
| LtuLFweQrj5Lfrje2hnNB7Y3TD4+yCM/cA4yTILixCe/B+N7LQysJgVDbW8u6BZQ | ||||
| 8ZqeDKOP6KCt37WhmcbT45tLpHmH+Z/uAnCz0hVc/7AyJ3CJXo6PaDCcJjgLuUun | ||||
| W47iy4h79AxyuzELmUeZZGYcO8nqClqcnAzQ6sClGZvJwSbYg2QAFGoA2lHqZ9uN | ||||
| ygAxNLd+rX9cP+yFwAeKzuKtOnVPiJD5lT3wufSkAbd6M7lOoqmTYnbv0A1WfA/e | ||||
| upXno9lbgB6iwF5U0V7OtxdA1bTbvgJgNLlxFF1do0sB28CWmqCFNwLfzcPzt5A4 | ||||
| gLnOyLhNZOmUMXn35KOtp1Zv/yethlgZHxUYGcl6OYwMEFye3Du6dgnTwONzaLhA | ||||
| 7hMI8R60p2YrTLkgSKdFohAY/mKuxHyXxugOHHthlRCOn9m49edcdZ1HrkJXm9jd | ||||
| P9katjCXgTwSdTQlvaMJkfH7wF3ZMjAxPcDf4RKFEpF2wABeNQIDAQABoD8wPQYJ | ||||
| KoZIhvcNAQkOMTAwLjAsBgNVHREEJTAjgg5jbG91ZGZsYXJlLmNvbYIRd3d3Y2xv | ||||
| dWRmbGFyZS5jb20wCwYJKoZIhvcNAQEMA4IBgQBF/RCHNAAOAaRI4VyO0tRPA5Dw | ||||
| 0/1/pgmBm/VejHIwDJnMFCl9njh0RSo1RgsVLhw6ovYbk3ORb4OD4UczPTq3GrFp | ||||
| KP9uPR+2pR4FWJpCVfCl76YabQv6fUDdiT7ojzyRhsAmkd5rOdiMvWV3Rp+YmBuU | ||||
| KH/dwkukfn+OeJIbERS5unzOBtQL+g5dU4CHWAqJQIqHr373w38OlYN+JY9QLrYy | ||||
| sWU9Ye6RjdySXPJ5UzyfOEfc9Ji89RJsVeceB1+As5u5vBvtzGgIMSFUzN947RZo | ||||
| DZ48JiB71VpmKXbn9LIRn25dlbVMzxRdSeZ194L3JFVAf9OxJTsc1QNFhOacoFgy | ||||
| hqvtN2iKntEyPo2nacYhpz/FAdJ2JThNH+4WtpPWAqx8Lw/e1OttiDt+6M0FEuVz | ||||
| svkSHnK206yo+a9Md37nUDDYxtlJEB+9F2qUZNQ7Hv+dxjmJOIgHOXxy1pLEdpVU | ||||
| rGdGLVXeJNPCh9x+GK21QjdxZABmYAaF8k36Pv4= | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										29
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa4096.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/cloudflare/cfssl/initca/testdata/rsa4096.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIFCTCCAvMCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl | ||||
| LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANkKL22jMn3eFCpj | ||||
| T6lbeq4nC3aEqwTGrLARidAmO29WIhzs6LxRpM6xSMoPI6DvJVUGpMFEKF4xNTc5 | ||||
| X9/gSFrw2eI5Q3U3aGcaToSCxH4hXejwIzX8Ftlb/LfpXhbSsFr5MS3kiTY4zZxM | ||||
| n3dSy2gZljD/g0tlQf5BdHdR4WKRhWnqRiGng+BmW4rjbcO7SoN33jSXsMcguCg5 | ||||
| 8dmYuf5G5KVXsqwEoCQBeKGnca9orcm4i90VnGt4qZUpfAn1cADzYGpRzX79USJ6 | ||||
| tol4ovgGPN08LJFqcVl+dK8VzJ03JWBhI1jePbWS4Bz5oNtkhQQXilU+G6FQxc6a | ||||
| UPf6KcFyOB+qMJmEwJZD9yaNK1YbsKfSztQEsb1JEezQnVHxp91Ch3AcWoikuOiY | ||||
| yCg0V5lcK15SLv1+5sj9YzF7ngMmThcIJ6B5gS3swpD5AX6FJaI1BrGwT/RXKKQP | ||||
| tRX1BySLx8RcINjFb5wv3q9QIE8vrW1BOk9f4dfmxiFYnc+6bCCbIrg7APQVtKTa | ||||
| ixNJFSqZz7fm9loeNPHHXfUT5RoW5yzVa8igc+yv4qeYsWHcZ4c/Y91OJp19HMjM | ||||
| bYm2alt8XagBgJjO0FW8wvsKwhhlhWK0WO6sQ7Fkl7fH1GtxEpc248hAW24SZMmS | ||||
| led3LblCT8IC3a9BLhqJ2q8cfPp9AgMBAAGgPzA9BgkqhkiG9w0BCQ4xMDAuMCwG | ||||
| A1UdEQQlMCOCDmNsb3VkZmxhcmUuY29tghF3d3djbG91ZGZsYXJlLmNvbTALBgkq | ||||
| hkiG9w0BAQ0DggIBAAgz3NuN43+F+8+WhQ9hb7DOp6Amut7XubOkEBtBVgP3R8U1 | ||||
| uSsgocR1rvnZ1/bhkeGyTly0eQPhcSEdMo/GgIrcn+co0KLcDyV6Rf3Cgksx9dUZ | ||||
| TzHSkxmFkxlxYfIGes6abH+2OPiacwK2gLvvmXFYIxEhv+LKzzteQi0xlinewv7R | ||||
| FnSykZ4QialsFyCgOjOxa11aEdRv6T8qKwhjUOk0VedtzOkt/k95aydTNLjXl2OV | ||||
| jloeTsbB00yWIqdyhG12+TgcJOa0pNP1zTjgFPodMuRUuiAcbT7Mt7sLCefKNzvZ | ||||
| Ln6b4y7e6N3YLOHALTIP+LI4y8ar47WlXCNw/zeOM2sW8udjYrukN6WOV3X68oMf | ||||
| Zsv6jqyGSaCDwdImR4VECUVvkabg9Sq4pz+ijTT+9cNA66omYL+/QAh0GahlROgW | ||||
| kDGI8zeEUoAC8RkAbFGMJA8jEbAfbT000ZwnLX2SZ8YRQX4Jd1FTmAH99FkvvT8N | ||||
| ovaGRSQQI5rWQGQYqF67So7PywEaEXeUHTBrv41Msva6CdaWHn7bh/fj4B21ETS7 | ||||
| VJvrk5DLJTyruqon7EVJU1pn38ppaXF4Z6a9n3C8TqudT/gdJUYn/SBo5jx20uGJ | ||||
| d9k6vDqixntvk/TRZ848k1AXiv5uUJTdnoPPhzSGjxEaeKuB0R1ZHomVdjU4 | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										162
									
								
								vendor/github.com/cloudflare/cfssl/log/log.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/cloudflare/cfssl/log/log.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | ||||
| // Package log implements a wrapper around the Go standard library's | ||||
| // logging package. Clients should set the current log level; only | ||||
| // messages below that level will actually be logged. For example, if | ||||
| // Level is set to LevelWarning, only log messages at the Warning, | ||||
| // Error, and Critical levels will be logged. | ||||
| package log | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| // The following constants represent logging levels in increasing levels of seriousness. | ||||
| const ( | ||||
| 	// LevelDebug is the log level for Debug statements. | ||||
| 	LevelDebug = iota | ||||
| 	// LevelInfo is the log level for Info statements. | ||||
| 	LevelInfo | ||||
| 	// LevelWarning is the log level for Warning statements. | ||||
| 	LevelWarning | ||||
| 	// LevelError is the log level for Error statements. | ||||
| 	LevelError | ||||
| 	// LevelCritical is the log level for Critical statements. | ||||
| 	LevelCritical | ||||
| 	// LevelFatal is the log level for Fatal statements. | ||||
| 	LevelFatal | ||||
| ) | ||||
|  | ||||
| var levelPrefix = [...]string{ | ||||
| 	LevelDebug:    "DEBUG", | ||||
| 	LevelInfo:     "INFO", | ||||
| 	LevelWarning:  "WARNING", | ||||
| 	LevelError:    "ERROR", | ||||
| 	LevelCritical: "CRITICAL", | ||||
| 	LevelFatal:    "FATAL", | ||||
| } | ||||
|  | ||||
| // Level stores the current logging level. | ||||
| var Level = LevelInfo | ||||
|  | ||||
| // SyslogWriter specifies the necessary methods for an alternate output | ||||
| // destination passed in via SetLogger. | ||||
| // | ||||
| // SyslogWriter is satisfied by *syslog.Writer. | ||||
| type SyslogWriter interface { | ||||
| 	Debug(string) | ||||
| 	Info(string) | ||||
| 	Warning(string) | ||||
| 	Err(string) | ||||
| 	Crit(string) | ||||
| 	Emerg(string) | ||||
| } | ||||
|  | ||||
| // syslogWriter stores the SetLogger() parameter. | ||||
| var syslogWriter SyslogWriter | ||||
|  | ||||
| // SetLogger sets the output used for output by this package. | ||||
| // A *syslog.Writer is a good choice for the logger parameter. | ||||
| // Call with a nil parameter to revert to default behavior. | ||||
| func SetLogger(logger SyslogWriter) { | ||||
| 	syslogWriter = logger | ||||
| } | ||||
|  | ||||
| func print(l int, msg string) { | ||||
| 	if l >= Level { | ||||
| 		if syslogWriter != nil { | ||||
| 			switch l { | ||||
| 			case LevelDebug: | ||||
| 				syslogWriter.Debug(msg) | ||||
| 			case LevelInfo: | ||||
| 				syslogWriter.Info(msg) | ||||
| 			case LevelWarning: | ||||
| 				syslogWriter.Warning(msg) | ||||
| 			case LevelError: | ||||
| 				syslogWriter.Err(msg) | ||||
| 			case LevelCritical: | ||||
| 				syslogWriter.Crit(msg) | ||||
| 			case LevelFatal: | ||||
| 				syslogWriter.Emerg(msg) | ||||
| 			} | ||||
| 		} else { | ||||
| 			log.Printf("[%s] %s", levelPrefix[l], msg) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func outputf(l int, format string, v []interface{}) { | ||||
| 	print(l, fmt.Sprintf(format, v...)) | ||||
| } | ||||
|  | ||||
| func output(l int, v []interface{}) { | ||||
| 	print(l, fmt.Sprint(v...)) | ||||
| } | ||||
|  | ||||
| // Fatalf logs a formatted message at the "fatal" level and then exits. The | ||||
| // arguments are handled in the same manner as fmt.Printf. | ||||
| func Fatalf(format string, v ...interface{}) { | ||||
| 	outputf(LevelFatal, format, v) | ||||
| 	os.Exit(1) | ||||
| } | ||||
|  | ||||
| // Fatal logs its arguments at the "fatal" level and then exits. | ||||
| func Fatal(v ...interface{}) { | ||||
| 	output(LevelFatal, v) | ||||
| 	os.Exit(1) | ||||
| } | ||||
|  | ||||
| // Criticalf logs a formatted message at the "critical" level. The | ||||
| // arguments are handled in the same manner as fmt.Printf. | ||||
| func Criticalf(format string, v ...interface{}) { | ||||
| 	outputf(LevelCritical, format, v) | ||||
| } | ||||
|  | ||||
| // Critical logs its arguments at the "critical" level. | ||||
| func Critical(v ...interface{}) { | ||||
| 	output(LevelCritical, v) | ||||
| } | ||||
|  | ||||
| // Errorf logs a formatted message at the "error" level. The arguments | ||||
| // are handled in the same manner as fmt.Printf. | ||||
| func Errorf(format string, v ...interface{}) { | ||||
| 	outputf(LevelError, format, v) | ||||
| } | ||||
|  | ||||
| // Error logs its arguments at the "error" level. | ||||
| func Error(v ...interface{}) { | ||||
| 	output(LevelError, v) | ||||
| } | ||||
|  | ||||
| // Warningf logs a formatted message at the "warning" level. The | ||||
| // arguments are handled in the same manner as fmt.Printf. | ||||
| func Warningf(format string, v ...interface{}) { | ||||
| 	outputf(LevelWarning, format, v) | ||||
| } | ||||
|  | ||||
| // Warning logs its arguments at the "warning" level. | ||||
| func Warning(v ...interface{}) { | ||||
| 	output(LevelWarning, v) | ||||
| } | ||||
|  | ||||
| // Infof logs a formatted message at the "info" level. The arguments | ||||
| // are handled in the same manner as fmt.Printf. | ||||
| func Infof(format string, v ...interface{}) { | ||||
| 	outputf(LevelInfo, format, v) | ||||
| } | ||||
|  | ||||
| // Info logs its arguments at the "info" level. | ||||
| func Info(v ...interface{}) { | ||||
| 	output(LevelInfo, v) | ||||
| } | ||||
|  | ||||
| // Debugf logs a formatted message at the "debug" level. The arguments | ||||
| // are handled in the same manner as fmt.Printf. | ||||
| func Debugf(format string, v ...interface{}) { | ||||
| 	outputf(LevelDebug, format, v) | ||||
| } | ||||
|  | ||||
| // Debug logs its arguments at the "debug" level. | ||||
| func Debug(v ...interface{}) { | ||||
| 	output(LevelDebug, v) | ||||
| } | ||||
							
								
								
									
										186
									
								
								vendor/github.com/cloudflare/cfssl/log/log_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								vendor/github.com/cloudflare/cfssl/log/log_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | ||||
| package log | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"log" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| const teststring = "asdf123" | ||||
|  | ||||
| func TestOutputf(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Level = LevelDebug | ||||
| 	outputf(LevelDebug, teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestOutput(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Level = LevelDebug | ||||
| 	output(LevelDebug, nil) | ||||
|  | ||||
| 	// outputf correctly prints string with proper Debug prefix | ||||
| 	if !strings.Contains(buf.String(), levelPrefix[LevelDebug]) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestCriticalf(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Criticalf(teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	// should never fail because critical > debug | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestCritical(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Critical(nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), levelPrefix[LevelCritical]) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestWarningf(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Warningf(teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	// should never fail because fatal critical > debug | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestWarning(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Warning(nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), levelPrefix[LevelWarning]) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestInfof(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Infof(teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	// should never fail because fatal info > debug | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestInfo(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Info(nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), levelPrefix[LevelInfo]) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestDebugf(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Level = LevelDebug | ||||
| 	Debugf(teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	// should never fail because fatal debug >= debug | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TestDebug(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	log.SetOutput(buf) | ||||
| 	Level = LevelDebug | ||||
| 	Debug(nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), levelPrefix[LevelDebug]) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| type testSyslogger struct { | ||||
| 	*bytes.Buffer | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Debug(s string) { | ||||
| 	l.WriteString("[DEBUG] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Info(s string) { | ||||
| 	l.WriteString("[INFO] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Warning(s string) { | ||||
| 	l.WriteString("[WARN] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Err(s string) { | ||||
| 	l.WriteString("[ERROR] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Crit(s string) { | ||||
| 	l.WriteString("[CRIT] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (l testSyslogger) Emerg(s string) { | ||||
| 	l.WriteString("[FATAL] ") | ||||
| 	_, _ = l.WriteString(s) | ||||
| } | ||||
|  | ||||
| func TestSetLogger(t *testing.T) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	SetLogger(testSyslogger{buf}) | ||||
| 	Level = LevelDebug | ||||
| 	outputf(LevelDebug, teststring, nil) | ||||
|  | ||||
| 	// outputf correctly prints string | ||||
| 	if !strings.Contains(buf.String(), teststring) { | ||||
| 		t.Fail() | ||||
| 	} | ||||
| 	SetLogger(nil) | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/config/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/config/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| // Package config in the ocsp directory provides configuration data for an OCSP | ||||
| // signer. | ||||
| package config | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| // Config contains configuration information required to set up an OCSP signer. | ||||
| type Config struct { | ||||
| 	CACertFile        string | ||||
| 	ResponderCertFile string | ||||
| 	KeyFile           string | ||||
| 	Interval          time.Duration | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| MIIEpAIBAAKCAQEAvKOCXwP8Y6x1YkjcimQafnP1bRCF/iWY+z4ffuTWA150RRpA | ||||
| GnhwOen8muU5wxOEm1A2IkWhNfXQ9GYVdOnzXumTx9Go4Gm8/1nRCYG69GZbQAEr | ||||
| pNGx/l4wReLVj2iizCf/xkcch5ZM/5zplXWZXCQiavmKz6M+1aSYdsGP0mrLu31c | ||||
| yod2iJmlISt+nuP5yXkgoKxzGrKjP5qrs6XniVXrKMt+5g1Ta5blWUoft2pwM6yp | ||||
| 8+IAtxh+iYTIJc8dDHbVl9AjVfsfaYeS8SkHcIRyIuD8/3HgLmP/gMLDzuLXvH+W | ||||
| slOEYqLGMkSo2JPOwLguggDyjt1rI2cEcFkgJwIDAQABAoIBAQCTAZW6+D87ag28 | ||||
| f22nR+XBwBp2WVcivSggO8SNvkXuMDDKHW/xcQR8jZW3HIZMOSyxYOwe/0Zn595k | ||||
| aB22lA9+Wuc45HIIGT8ZfGREVV5d0lqwYXkio+xjgAF8pQ6rCO89zLouSgK4w2/U | ||||
| D/OU7yWJwfs0hK4hrGVuVywd+DBd2Fc7UfZ4oEcy89mwUIRVK8+eXrRCav6lGDrz | ||||
| I+GmW6GL16U8lS8vsUNciYyNYCzgSIIa/yyiZO/Aje93yJRVpmujAK2p6/w/7vmK | ||||
| OareeixlpNYpiY7Nk6o3w6sKEEVzf+AquDgeH5IkzD1nkYbd+JY7bdg1cgjz3kJg | ||||
| IhsiIER5AoGBAOkZpicTIsiAMxz43bzMt1IMYu1ezAEw4Vk2sVEbSfFXdbO5J9gW | ||||
| /Ou+AhwxhsDeO6vgh3mYkG+2s5U+ztk68X1BVIf87kYBQiz175XvxcLmDBFm5S6g | ||||
| eyTCwsop9J4XlgQQ5HNm80G9oHnF50oujCqpUiC5xj5fEd8vULmua5jTAoGBAM8r | ||||
| rTTpVBHKArDlzYF5EpyXDkcFT2uAgw9Xpc6xIl/UWQ+XU1qD5Te0fmjpdwo3VZTL | ||||
| W2e8eg0U9O2skrxBcRLREnh1U2znCMSIGTkwYQ2JDjhz2Jjbh8r/NhvSdydql9wQ | ||||
| LGyPOIpcURaD+ohOExF82EtEqWgNp4QfQHH70cbdAoGAPBoy7yxN8aishTHd6opW | ||||
| Uj+DWnTw4PW7hQdHHQSOQj4syRRao6r5t8ccQCy89AnZFO4lwEKIK2XOVBMHvpcm | ||||
| IQexRgb/YOl+KJ2ZEu3p7eDnB62iNi2G0ums0/eRbRnjwlSgsui+nBrKv9s5UbVC | ||||
| ytUxqeJ8rSRSNVu70sSYVaUCgYALYUrSbT7A+2fKb9UqF4x+LY4LOK90KEsKvLXO | ||||
| 9Mv+l5uMz7M0dapRtQh8mtZ/KSr6UXFj8WaC8XPC2of072NWtUVeeJNsmARTR2ab | ||||
| TZ0HMVAmqbZsLyL2c651OMpyz9gnrnvCOtvQPeH2aqmIc0F45HK9L7hejuF00IKp | ||||
| wDt1wQKBgQC8sjlF/8e03m3AfLs2ZW/w0Rsggz52TgBdH24BMUmvd5McVZlH8uZq | ||||
| zwx5ht3ppVjObG28JPEj8c/FtAmsUjURDD7EVdjb5bDxrMtH++8sHrXUuMMBeUxl | ||||
| DN2IU+xL9MwMh5H0cyJbXnE+LWGpSefCccDnH5qlEjwNXE5/RggOrw== | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIDvjCCAqigAwIBAgIIWhorb65IXvUwCwYJKoZIhvcNAQELMG0xCzAJBgNVBAYT | ||||
| AlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2lu | ||||
| ZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9y | ||||
| bmlhMB4XDTE1MDQxOTE2MTAwMFoXDTIwMDQxNzE2MTAwMFowbTELMAkGA1UEBhMC | ||||
| VVMxEzARBgNVBAoTCkNsb3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5l | ||||
| ZXJpbmcxFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3Ju | ||||
| aWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8o4JfA/xjrHViSNyK | ||||
| ZBp+c/VtEIX+JZj7Ph9+5NYDXnRFGkAaeHA56fya5TnDE4SbUDYiRaE19dD0ZhV0 | ||||
| 6fNe6ZPH0ajgabz/WdEJgbr0ZltAASuk0bH+XjBF4tWPaKLMJ//GRxyHlkz/nOmV | ||||
| dZlcJCJq+YrPoz7VpJh2wY/Sasu7fVzKh3aImaUhK36e4/nJeSCgrHMasqM/mquz | ||||
| peeJVesoy37mDVNrluVZSh+3anAzrKnz4gC3GH6JhMglzx0MdtWX0CNV+x9ph5Lx | ||||
| KQdwhHIi4Pz/ceAuY/+AwsPO4te8f5ayU4RiosYyRKjYk87AuC6CAPKO3WsjZwRw | ||||
| WSAnAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIABjASBgNVHRMBAf8ECDAGAQH/AgEC | ||||
| MB0GA1UdDgQWBBSrzjPP4Y5PLsqeyp6iddofBjoRmTAfBgNVHSMEGDAWgBSrzjPP | ||||
| 4Y5PLsqeyp6iddofBjoRmTALBgkqhkiG9w0BAQsDggEBAH7McpSm7+DeIZPQKYpF | ||||
| kFUlNn3N4MRvek5lxOw6jLE1QmzG3lTB79g6iBiGKsYLPoJqNS6VxMoLrMC+qFhM | ||||
| 0QM5eIzRpdfYa83IDIYcbUYx7fLG/azX+FMFh/O5yPtS+bqbxGinxofRIyuKGs9r | ||||
| dks6I5lGncRs0Liysp4mHJAjyj9G2W2onI3Y00BYhiOy4mYvZ5/S31KI4550HZ+p | ||||
| dnexuC29CsWGkOTXTOS7+e7Zmbh8UjsYcA5YOojew+EjJfETPVO+Pn7WGg/+XrFX | ||||
| 8UOG3o9k8M0ePQof4R6FTJ+BQxtSkWWdp1HrMQbZ1TXfZx84XkmFdcmy8FjYiHbP | ||||
| M+M= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIID4TCCAsugAwIBAgIIEoDcqfKl/s4wCwYJKoZIhvcNAQELMG0xCzAJBgNVBAYT | ||||
| AlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2lu | ||||
| ZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9y | ||||
| bmlhMB4XDTE1MDQxOTE2MTkwMFoXDTE2MDQxODE2MTkwMFowXTELMAkGA1UEBhMC | ||||
| VVMxEDAOBgNVBAoTB0V4YW1wbGUxDzANBgNVBAsTBlRoaW5nczEWMBQGA1UEBxMN | ||||
| U2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcN | ||||
| AQEBBQADggEPADCCAQoCggEBAK7jUnRUeD5QY9YPjbW6aiGkVWRWAebi4nZl++C+ | ||||
| HEBHSyB0jXX+J93y97PuhgeguCuMM6KZU7C0tPZKjwdxBSqpXeyFpvcj+UWMjZjz | ||||
| 9FrBAzZ1DIYquqfYuKUtavoFv29IomRqzyZ4FrMJ2qy0RudnWMTqn4P6/7DrWos+ | ||||
| oJMCpl/mdWl+YXMXypgW5JwM7ladx8GkEKQwGMtXrG9pop7qS6LNikN76tLPYWjR | ||||
| DhrWLBe8gCGjuXkwvxw78CeeJNyWF+P/+x4lVsWphip3jX57SUx/bjaRjsWSfpMz | ||||
| xHueHtuCrGffgCkFzYH1/Z60FZNxuHYqJeL4V3gcR8IIaZECAwEAAaOBmDCBlTAO | ||||
| BgNVHQ8BAf8EBAMCAKAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwG | ||||
| A1UdEwEB/wQCMAAwHQYDVR0OBBYEFBnFrxc1gkG2CYImTYKL0DAaGxRBMB8GA1Ud | ||||
| IwQYMBaAFKvOM8/hjk8uyp7KnqJ12h8GOhGZMBYGA1UdEQQPMA2CC2V4YW1wbGUu | ||||
| Y29tMAsGCSqGSIb3DQEBCwOCAQEAX31Jk7R9gDMw/gepIxxeKx9m+c7eOYDxjJ12 | ||||
| bfXQVKNNPLZsO9M9r2/0BCTFsNTF2jh6ZTeIf7qy+Jw08YqTcO5m8jhiGzCjOYu5 | ||||
| tiGxCUe+cYjXcCRk83+XGkVrQm3fQ0cVtic0yfm/fez3iv915jH0GYO5X8/d7bKa | ||||
| 0kWJ3uOjur6tenfnisypEsuYYjPRcQdXSG6/qgHEc4r279Z2ltjy1bFFr86hHUbj | ||||
| DX7XNWH/MXFgqLzfQm5VzmqBj9om+0/tgTWdkgI1DK/Hnvm9A4YZfaxh4fxv7ITo | ||||
| Ce8FWW13Wj55x64peb8ZiW1jUyoaJQcxQxFpRHIVu26nXApWtg== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/db-config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/db-config.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| {"driver":"sqlite3","data_source":"sqlite_test.db"} | ||||
							
								
								
									
										2
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| MIIFCAoBAKCCBQEwggT9BgkrBgEFBQcwAQEEggTuMIIE6jCBrKADAgEAoS0wKzEpMCcGA1UEAwwgY2Fja2xpbmcgY3J5cHRvZ3JhcGhlciBmYWtlIFJPT1QYDzIwMTUxMDIxMjEyNjAwWjBlMGMwOzAJBgUrDgMCGgUABBSwLsMRhyg1dJUwnXWk++D57lvgagQU6aQ/7p6l5vLV13lgPJOmLiSOl6oCAhJNgAAYDzIwMTUwOTAxMDAwMDAwWqARGA8yMDE0MDEwMTAwMDAwMFowDQYJKoZIhvcNAQELBQADggEBAHlFcNKa7mZDJeWzJt1S45kx4gDqOLzyeZzflFbSjsrHRrLA7Y3RKoy0i4Y9Vi6Jfhe7xj6dgDMJy1Z1qayI/Q8QvnaU6V2kFcnaD7pah9uALu2xNYMJPllq8KsQYvDLa1E2PMvQTqDhY2/QrIuxw3jkqtzeI5aG0idFm3aF1z/v3dt6XPWjE8IlAJfXY4CeUorLvA+mK2YHJ3V7MSgymVXZdyth1rg0/0cP9v77Rlb8hmWA/EUMcIPKQqErVQK+gZiVC0SfElaMO25CD9cjY+fd904oC5+ahvhHXxOSEbXVZBT1FY2teFCKEpx86gAVcZWpGmVwJO+dpsrkgwpN786gggMjMIIDHzCCAxswggIDoAMCAQICCQDNMc/iNkPNdTANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBjYWNrbGluZyBjcnlwdG9ncmFwaGVyIGZha2UgUk9PVDAeFw0xNTEwMjEyMDExNTJaFw0yMDEwMTkyMDExNTJaMCsxKTAnBgNVBAMMIGNhY2tsaW5nIGNyeXB0b2dyYXBoZXIgZmFrZSBST09UMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+TbvalHXQYO6GhJUJZI5mF2k4+nZDIvqWyrjw+2k9+UAcekuLKPpSclu9aBRvUggw3XFHAW95qW6Dv2+5gvinUmTq9Ry7kVTUYAxyZu1ydHt+wDETmFJfeY6/fpBHHIsuGLItqpUGmr8D6LROGEqfFY2B9+08O7Zs+FufDRgLHWEvLTdpPkrzeDJs9Oo6g38jfT9b4+9Ahs+FvvwqneAkbeZgBC2NWKB+drMuNBTPbF/W1a8czAzHeOs6qy0dBlTHNjL62/o9cRKNiKe3IqwHJdd01V1aLSUgIbe2HrP9EC1djnUXWR3jx3ursaKt7PTKsC52UJkRqnai80MzQj0WwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU6aQ/7p6l5vLV13lgPJOmLiSOl6owDQYJKoZIhvcNAQELBQADggEBACuwILDTvaBrdorv2zMsYnZuKvXtknWAf/DTcvF4N5PMOPBNkeHuGfv0VDe6VXpBHiU5G9E2RdU435W7o0kRSn27YcqrxaXGt9m2kArW6e49136+MnFx47jjk0p4T48s6MeaL5JVLJzxYouu1ZOZqlVokwNPO+8bxn6ALumIVUOD1jSBN7Y9pgLUS2rzO5pe5pxS2Ak/eO7Q7M21r1sEuG/uPuWqBFogk+4Z9omKVZdRDbzm9vYUATgEZdlTe2tct3BVBQ2zWbe0R2svIuCs8XzERykvfv1JawxI68I9vN0Dh9vj/xDM6udorfALlhjgQdftmbHovRLpJ1ZSOMIUNGY= | ||||
| MIIFCAoBAKCCBQEwggT9BgkrBgEFBQcwAQEEggTuMIIE6jCBrKADAgEAoS0wKzEpMCcGA1UEAwwgY2Fja2xpbmcgY3J5cHRvZ3JhcGhlciBmYWtlIFJPT1QYDzIwMTUxMDIxMjA1NTAwWjBlMGMwOzAJBgUrDgMCGgUABBSwLsMRhyg1dJUwnXWk++D57lvgagQU6aQ/7p6l5vLV13lgPJOmLiSOl6oCAhJNgAAYDzIwMTUxMDIwMDAwMDAwWqARGA8yMDMwMTAyMDAwMDAwMFowDQYJKoZIhvcNAQELBQADggEBAFgnZ/Ft1LTDYPwPlecOtLykgwS4HZTelUaSi841nq/tgfLM11G3D1AUXAT2V2jxiG+0YTxzkWd5v44KJGB9Mm+qjafPMKR3ULjQkJHJ8goFHpWkUtLrIYurj8N+4HpwZ+RJccieuZIX8SMeSWRq5w83okWZPGoUrl6GRdQDteE7imrNkBa35zrzUWozPqY8k90ttKfhZHRXNCJe8YbVfJRDh0vVZABzlfHeW8V+ie15HPVDx/M341KC3tBMM88e5/bt3sLyUU8SwxGH5nOe/ohVpjhkjk2Pz4TPdwD2ZK5Auc09VBfivdLYRE84BMhd8/yOEt53VWGPIMxWUVtrUyegggMjMIIDHzCCAxswggIDoAMCAQICCQDNMc/iNkPNdTANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBjYWNrbGluZyBjcnlwdG9ncmFwaGVyIGZha2UgUk9PVDAeFw0xNTEwMjEyMDExNTJaFw0yMDEwMTkyMDExNTJaMCsxKTAnBgNVBAMMIGNhY2tsaW5nIGNyeXB0b2dyYXBoZXIgZmFrZSBST09UMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+TbvalHXQYO6GhJUJZI5mF2k4+nZDIvqWyrjw+2k9+UAcekuLKPpSclu9aBRvUggw3XFHAW95qW6Dv2+5gvinUmTq9Ry7kVTUYAxyZu1ydHt+wDETmFJfeY6/fpBHHIsuGLItqpUGmr8D6LROGEqfFY2B9+08O7Zs+FufDRgLHWEvLTdpPkrzeDJs9Oo6g38jfT9b4+9Ahs+FvvwqneAkbeZgBC2NWKB+drMuNBTPbF/W1a8czAzHeOs6qy0dBlTHNjL62/o9cRKNiKe3IqwHJdd01V1aLSUgIbe2HrP9EC1djnUXWR3jx3ursaKt7PTKsC52UJkRqnai80MzQj0WwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU6aQ/7p6l5vLV13lgPJOmLiSOl6owDQYJKoZIhvcNAQELBQADggEBACuwILDTvaBrdorv2zMsYnZuKvXtknWAf/DTcvF4N5PMOPBNkeHuGfv0VDe6VXpBHiU5G9E2RdU435W7o0kRSn27YcqrxaXGt9m2kArW6e49136+MnFx47jjk0p4T48s6MeaL5JVLJzxYouu1ZOZqlVokwNPO+8bxn6ALumIVUOD1jSBN7Y9pgLUS2rzO5pe5pxS2Ak/eO7Q7M21r1sEuG/uPuWqBFogk+4Z9omKVZdRDbzm9vYUATgEZdlTe2tct3BVBQ2zWbe0R2svIuCs8XzERykvfv1JawxI68I9vN0Dh9vj/xDM6udorfALlhjgQdftmbHovRLpJ1ZSOMIUNGY= | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response.der
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| MIICGAoBAKCCAhEwggINBgkrBgEFBQcwAQEEggH+OZ4ZSKS2J85Kr9UaI2LAEFKvOM8/hjk8uyp7KnqJ12h8GOhGZAgIBdaADAQH/GA8wMDAxMDEwMTAwMDAwMFqgERgPMDAwMTAxMDEwMDAwMDBaMA0GCSqGSIb3DQEBCwUAA4IBAQCBGs+8UNwUdkEBladnajZIV+sHtmao/mMTIvpyPqnmV2Ab9KfNWlSDSDuMtZYKS4VsEwtbZ+4kKWI8DugE6egjP3o64R7VP2aqrh41IORwccLGVsexILBpxg4h602JbhXM0sxgXoh5WAt9f1oy6PsHAt/XAuJGSo7yMNv3nHKNFwjExmZt21sNLYlWlljjtX92rlo/mBTWKO0js4YRNyeNQhchARbn9oL18jW0yAVqB9a8rees+EippbTfoktFf0cIhnmkiknPZSZ+dN2qHkxiXIujWlymZzUZcqRTNtrmmhlOdt35QSg7Vw8eyw2rl8ZU94zaI5DPWn1QYn0dk7l9 | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response_mix.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/response_mix.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server.crt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server.crt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIICATCCAWoCCQDidF+uNJR6czANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB | ||||
| VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 | ||||
| cyBQdHkgTHRkMB4XDTEyMDUwMTIyNTUxN1oXDTEzMDUwMTIyNTUxN1owRTELMAkG | ||||
| A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 | ||||
| IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtpjl | ||||
| nodhz31kLEJoeLSkRmrv8l7exkGtO0REtIbirj9BBy64ZXVBE7khKGO2cnM8U7yj | ||||
| w7Ntfh+IvCjZVA3d2XqHS3Pjrt4HmU/cGCONE8+NEXoqdzLUDPOix1qDDRBvXs81 | ||||
| KAV2qh6CYHZbdqixhDerjvJcD4Nsd7kExEZfHuECAwEAATANBgkqhkiG9w0BAQUF | ||||
| AAOBgQCyOqs7+qpMrYCgL6OamDeCVojLoEp036PsnaYWf2NPmsVXdpYW40Foyyjp | ||||
| iv5otkxO5rxtGPv7o2J1eMBpCuSkydvoz3Ey/QwGqbBwEXQ4xYCgra336gqW2KQt | ||||
| +LnDCkE8f5oBhCIisExc2i8PDvsRsY70g/2gs983ImJjVR8sDw== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| MIICXAIBAAKBgQC2mOWeh2HPfWQsQmh4tKRGau/yXt7GQa07RES0huKuP0EHLrhl | ||||
| dUETuSEoY7ZyczxTvKPDs21+H4i8KNlUDd3ZeodLc+Ou3geZT9wYI40Tz40Reip3 | ||||
| MtQM86LHWoMNEG9ezzUoBXaqHoJgdlt2qLGEN6uO8lwPg2x3uQTERl8e4QIDAQAB | ||||
| AoGAVxnsPojZ8X4g8LPk3d9dlXGhb/4tSmk9102jcHH/Y5ssy95Pe6ZJGr1uwbN+ | ||||
| 7m1l05PikpHeoxEryoW51cyfjDVkXUT0zPp2JC38DUA/0A8qWav/aENM64wg1I0P | ||||
| Dil8FywzZEonRNJst53+9cxFye70ely5br/tWxEp4/MsM1kCQQDqV4Lwn8BXOeKg | ||||
| xOwNmcL+0XPedvSPBSPUoGJCzu12rH6Z+UHXipXsqRNSyQ+KGlur14y0kCh5uiVA | ||||
| jmWYVEEjAkEAx3keAo1nFsVW35EPt5LIbh6L6ty7GrvGRvOVeSd6YLtixMety24k | ||||
| hpt1cEv2xlFnbjbBbMkr9eUiUNpttLT6KwJBANGKaLoSjqEwUFYjX1OV/wdtcGcn | ||||
| BOzx0qUouFQ2xZ0NBrNVbyt1bzPLx0yKHkwF35ybw+Qc1yRpby/3ZB6+j/MCQFLl | ||||
| vtcItOL9uBDJVGLSGYHKKBO/D/MYPlqWOHRVN8KjnXRyF4QHjh5y1OeKalAY3Ict | ||||
| Mk1nfWF/jDdVz2neHGkCQHHBR4Xt1/euDku+14z5aLpphTEQVuRD2vQoeKi/W/CY | ||||
| OgNmKj1DzucnCS6yRCrF8Q0Pn8l054a3Wdbl1gqI/gA= | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										9
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtpjl | ||||
| nodhz31kLEJoeLSkRmrv8l7exkGtO0REtIbirj9BBy64ZXVBE7khKGO2cnM8U7yj | ||||
| w7Ntfh+IvCjZVA3d2XqHS3Pjrt4HmU/cGCONE8+NEXoqdzLUDPOix1qDDRBvXs81 | ||||
| KAV2qh6CYHZbdqixhDerjvJcD4Nsd7kExEZfHuECAwEAATANBgkqhkiG9w0BAQUF | ||||
| AAOBgQCyOqs7+qpMrYCgL6OamDeCVojLoEp036PsnaYWf2NPmsVXdpYW40Foyyjp | ||||
| iv5otkxO5rxtGPv7o2J1eMBpCuSkydvoz3Ey/QwGqbBwEXQ4xYCgra336gqW2KQt | ||||
| +LnDCkE8f5oBhCIisExc2i8PDvsRsY70g/2gs983ImJjVR8sDw== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										8
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| jmWYVEEjAkEAx3keAo1nFsVW35EPt5LIbh6L6ty7GrvGRvOVeSd6YLtixMety24k | ||||
| hpt1cEv2xlFnbjbBbMkr9eUiUNpttLT6KwJBANGKaLoSjqEwUFYjX1OV/wdtcGcn | ||||
| BOzx0qUouFQ2xZ0NBrNVbyt1bzPLx0yKHkwF35ybw+Qc1yRpby/3ZB6+j/MCQFLl | ||||
| vtcItOL9uBDJVGLSGYHKKBO/D/MYPlqWOHRVN8KjnXRyF4QHjh5y1OeKalAY3Ict | ||||
| Mk1nfWF/jDdVz2neHGkCQHHBR4Xt1/euDku+14z5aLpphTEQVuRD2vQoeKi/W/CY | ||||
| OgNmKj1DzucnCS6yRCrF8Q0Pn8l054a3Wdbl1gqI/gA= | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										22
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/sqlite_ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/sqlite_ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIDqjCCApKgAwIBAgIUFqT7NscPhQ5kfZTYNhWTKXVekrswDQYJKoZIhvcNAQEL | ||||
| BQAwbTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMQ8wDQYDVQQHEwZJ | ||||
| dGhhY2ExLDAqBgNVBAoTI1RoZSBCZXN0IE9wZW4tU291cmNlIEhhY2thdGhvbiBU | ||||
| ZWFtMQwwCgYDVQQLEwNXV1cwHhcNMTcwMjExMTQxMDAwWhcNMjIwMjEwMTQxMDAw | ||||
| WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxDzANBgNVBAcTBkl0 | ||||
| aGFjYTEsMCoGA1UEChMjVGhlIEJlc3QgT3Blbi1Tb3VyY2UgSGFja2F0aG9uIFRl | ||||
| YW0xDDAKBgNVBAsTA1dXVzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB | ||||
| ANR66Ky8dBV2FVyDOGXFM4bF63EJxI7PgCKg8yiJsYihwo5wsABpiI66offWsJNV | ||||
| rRKT8QhGohm4V1B/MOpdb3slOYVFXAInjoKyClPYDK3GMkJ8mo6mFysm3q/JqlEl | ||||
| KjvVIb8Yq7cgPAj/MOb4rBJu5+c3sM37CwpUbxCTdPiuVMGYDjVKauloJfTir0HQ | ||||
| RMwREsO6fyzSia4qvfj4ljWGzPtEVrRmzs7LguLr3DkUjXMSq7AI3L+oUdiYR6kV | ||||
| c3rLucMQKRCNGMcU3T8Sq9Pwt2sUeAFNqcXk9E1FqesYwFoEejStU24wpTd4ah0g | ||||
| tL1LyoEYG6etUehrxlRlMJsCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud | ||||
| EwEB/wQFMAMBAf8wHQYDVR0OBBYEFANQ4+9iVQzAZdHhb0fNXtrb3krdMA0GCSqG | ||||
| SIb3DQEBCwUAA4IBAQA4SKVpdJj40xaeyVkHWtrY4O8wB2J7Z6rsUf9jlEySeQaH | ||||
| GWI4LUOKjrU0u/NtuvTybDHyfc1VrdgZmfaukE35VyQ1+xWa/47Q7KISSCH1x0cF | ||||
| L+WdJqKHD0q/tR2uz/fw9AUlV1LkBEeAZclhPxCLv32gLExQrNCBVa7c9Xkq1muB | ||||
| o0ootJF9sTZopqnsMldvMBWOl/9cb2dxPKu3AcNpCm28wt+rwqHIu+Fna9Fe/n+y | ||||
| SmWTaP3l/eiLskFUvmHKSUVwTEPC6kbK9rxKPz7ijQ3h/YuWxxz32L2CpsOfekgT | ||||
| 7jER0Y/xxZq7XykdwZ1VKKfZGnsH8mU2rU335Gd1 | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/sqlite_test.db
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/github.com/cloudflare/cfssl/ocsp/testdata/sqlite_test.db
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										556
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/local.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										556
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/local.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,556 @@ | ||||
| // Package local implements certificate signature functionality for CFSSL. | ||||
| package local | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"encoding/hex" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"math/big" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"net/mail" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/cloudflare/cfssl/certdb" | ||||
| 	"github.com/cloudflare/cfssl/config" | ||||
| 	cferr "github.com/cloudflare/cfssl/errors" | ||||
| 	"github.com/cloudflare/cfssl/helpers" | ||||
| 	"github.com/cloudflare/cfssl/info" | ||||
| 	"github.com/cloudflare/cfssl/log" | ||||
| 	"github.com/cloudflare/cfssl/signer" | ||||
| 	"github.com/google/certificate-transparency-go" | ||||
| 	"github.com/google/certificate-transparency-go/client" | ||||
| 	"github.com/google/certificate-transparency-go/jsonclient" | ||||
| 	"golang.org/x/net/context" | ||||
| ) | ||||
|  | ||||
| // Signer contains a signer that uses the standard library to | ||||
| // support both ECDSA and RSA CA keys. | ||||
| type Signer struct { | ||||
| 	ca         *x509.Certificate | ||||
| 	priv       crypto.Signer | ||||
| 	policy     *config.Signing | ||||
| 	sigAlgo    x509.SignatureAlgorithm | ||||
| 	dbAccessor certdb.Accessor | ||||
| } | ||||
|  | ||||
| // NewSigner creates a new Signer directly from a | ||||
| // private key and certificate, with optional policy. | ||||
| func NewSigner(priv crypto.Signer, cert *x509.Certificate, sigAlgo x509.SignatureAlgorithm, policy *config.Signing) (*Signer, error) { | ||||
| 	if policy == nil { | ||||
| 		policy = &config.Signing{ | ||||
| 			Profiles: map[string]*config.SigningProfile{}, | ||||
| 			Default:  config.DefaultConfig()} | ||||
| 	} | ||||
|  | ||||
| 	if !policy.Valid() { | ||||
| 		return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) | ||||
| 	} | ||||
|  | ||||
| 	return &Signer{ | ||||
| 		ca:      cert, | ||||
| 		priv:    priv, | ||||
| 		sigAlgo: sigAlgo, | ||||
| 		policy:  policy, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // NewSignerFromFile generates a new local signer from a caFile | ||||
| // and a caKey file, both PEM encoded. | ||||
| func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signer, error) { | ||||
| 	log.Debug("Loading CA: ", caFile) | ||||
| 	ca, err := helpers.ReadBytes(caFile) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	log.Debug("Loading CA key: ", caKeyFile) | ||||
| 	cakey, err := helpers.ReadBytes(caKeyFile) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.ReadFailed, err) | ||||
| 	} | ||||
|  | ||||
| 	parsedCa, err := helpers.ParseCertificatePEM(ca) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	strPassword := os.Getenv("CFSSL_CA_PK_PASSWORD") | ||||
| 	password := []byte(strPassword) | ||||
| 	if strPassword == "" { | ||||
| 		password = nil | ||||
| 	} | ||||
|  | ||||
| 	priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password) | ||||
| 	if err != nil { | ||||
| 		log.Debug("Malformed private key %v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return NewSigner(priv, parsedCa, signer.DefaultSigAlgo(priv), policy) | ||||
| } | ||||
|  | ||||
| func (s *Signer) sign(template *x509.Certificate) (cert []byte, err error) { | ||||
| 	var initRoot bool | ||||
| 	if s.ca == nil { | ||||
| 		if !template.IsCA { | ||||
| 			err = cferr.New(cferr.PolicyError, cferr.InvalidRequest) | ||||
| 			return | ||||
| 		} | ||||
| 		template.DNSNames = nil | ||||
| 		template.EmailAddresses = nil | ||||
| 		s.ca = template | ||||
| 		initRoot = true | ||||
| 	} | ||||
|  | ||||
| 	derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) | ||||
| 	} | ||||
| 	if initRoot { | ||||
| 		s.ca, err = x509.ParseCertificate(derBytes) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) | ||||
| 	log.Infof("signed certificate with serial number %d", template.SerialNumber) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // replaceSliceIfEmpty replaces the contents of replaced with newContents if | ||||
| // the slice referenced by replaced is empty | ||||
| func replaceSliceIfEmpty(replaced, newContents *[]string) { | ||||
| 	if len(*replaced) == 0 { | ||||
| 		*replaced = *newContents | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // PopulateSubjectFromCSR has functionality similar to Name, except | ||||
| // it fills the fields of the resulting pkix.Name with req's if the | ||||
| // subject's corresponding fields are empty | ||||
| func PopulateSubjectFromCSR(s *signer.Subject, req pkix.Name) pkix.Name { | ||||
| 	// if no subject, use req | ||||
| 	if s == nil { | ||||
| 		return req | ||||
| 	} | ||||
|  | ||||
| 	name := s.Name() | ||||
|  | ||||
| 	if name.CommonName == "" { | ||||
| 		name.CommonName = req.CommonName | ||||
| 	} | ||||
|  | ||||
| 	replaceSliceIfEmpty(&name.Country, &req.Country) | ||||
| 	replaceSliceIfEmpty(&name.Province, &req.Province) | ||||
| 	replaceSliceIfEmpty(&name.Locality, &req.Locality) | ||||
| 	replaceSliceIfEmpty(&name.Organization, &req.Organization) | ||||
| 	replaceSliceIfEmpty(&name.OrganizationalUnit, &req.OrganizationalUnit) | ||||
| 	if name.SerialNumber == "" { | ||||
| 		name.SerialNumber = req.SerialNumber | ||||
| 	} | ||||
| 	return name | ||||
| } | ||||
|  | ||||
| // OverrideHosts fills template's IPAddresses, EmailAddresses, and DNSNames with the | ||||
| // content of hosts, if it is not nil. | ||||
| func OverrideHosts(template *x509.Certificate, hosts []string) { | ||||
| 	if hosts != nil { | ||||
| 		template.IPAddresses = []net.IP{} | ||||
| 		template.EmailAddresses = []string{} | ||||
| 		template.DNSNames = []string{} | ||||
| 	} | ||||
|  | ||||
| 	for i := range hosts { | ||||
| 		if ip := net.ParseIP(hosts[i]); ip != nil { | ||||
| 			template.IPAddresses = append(template.IPAddresses, ip) | ||||
| 		} else if email, err := mail.ParseAddress(hosts[i]); err == nil && email != nil { | ||||
| 			template.EmailAddresses = append(template.EmailAddresses, email.Address) | ||||
| 		} else { | ||||
| 			template.DNSNames = append(template.DNSNames, hosts[i]) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| // Sign signs a new certificate based on the PEM-encoded client | ||||
| // certificate or certificate request with the signing profile, | ||||
| // specified by profileName. | ||||
| func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { | ||||
| 	profile, err := signer.Profile(s, req.Profile) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	block, _ := pem.Decode([]byte(req.Request)) | ||||
| 	if block == nil { | ||||
| 		return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) | ||||
| 	} | ||||
|  | ||||
| 	if block.Type != "NEW CERTIFICATE REQUEST" && block.Type != "CERTIFICATE REQUEST" { | ||||
| 		return nil, cferr.Wrap(cferr.CSRError, | ||||
| 			cferr.BadRequest, errors.New("not a csr")) | ||||
| 	} | ||||
|  | ||||
| 	csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Copy out only the fields from the CSR authorized by policy. | ||||
| 	safeTemplate := x509.Certificate{} | ||||
| 	// If the profile contains no explicit whitelist, assume that all fields | ||||
| 	// should be copied from the CSR. | ||||
| 	if profile.CSRWhitelist == nil { | ||||
| 		safeTemplate = *csrTemplate | ||||
| 	} else { | ||||
| 		if profile.CSRWhitelist.Subject { | ||||
| 			safeTemplate.Subject = csrTemplate.Subject | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.PublicKeyAlgorithm { | ||||
| 			safeTemplate.PublicKeyAlgorithm = csrTemplate.PublicKeyAlgorithm | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.PublicKey { | ||||
| 			safeTemplate.PublicKey = csrTemplate.PublicKey | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.SignatureAlgorithm { | ||||
| 			safeTemplate.SignatureAlgorithm = csrTemplate.SignatureAlgorithm | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.DNSNames { | ||||
| 			safeTemplate.DNSNames = csrTemplate.DNSNames | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.IPAddresses { | ||||
| 			safeTemplate.IPAddresses = csrTemplate.IPAddresses | ||||
| 		} | ||||
| 		if profile.CSRWhitelist.EmailAddresses { | ||||
| 			safeTemplate.EmailAddresses = csrTemplate.EmailAddresses | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if req.CRLOverride != "" { | ||||
| 		safeTemplate.CRLDistributionPoints = []string{req.CRLOverride} | ||||
| 	} | ||||
|  | ||||
| 	if safeTemplate.IsCA { | ||||
| 		if !profile.CAConstraint.IsCA { | ||||
| 			log.Error("local signer policy disallows issuing CA certificate") | ||||
| 			return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) | ||||
| 		} | ||||
|  | ||||
| 		if s.ca != nil && s.ca.MaxPathLen > 0 { | ||||
| 			if safeTemplate.MaxPathLen >= s.ca.MaxPathLen { | ||||
| 				log.Error("local signer certificate disallows CA MaxPathLen extending") | ||||
| 				// do not sign a cert with pathlen > current | ||||
| 				return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) | ||||
| 			} | ||||
| 		} else if s.ca != nil && s.ca.MaxPathLen == 0 && s.ca.MaxPathLenZero { | ||||
| 			log.Error("local signer certificate disallows issuing CA certificate") | ||||
| 			// signer has pathlen of 0, do not sign more intermediate CAs | ||||
| 			return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	OverrideHosts(&safeTemplate, req.Hosts) | ||||
| 	safeTemplate.Subject = PopulateSubjectFromCSR(req.Subject, safeTemplate.Subject) | ||||
|  | ||||
| 	// If there is a whitelist, ensure that both the Common Name and SAN DNSNames match | ||||
| 	if profile.NameWhitelist != nil { | ||||
| 		if safeTemplate.Subject.CommonName != "" { | ||||
| 			if profile.NameWhitelist.Find([]byte(safeTemplate.Subject.CommonName)) == nil { | ||||
| 				return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) | ||||
| 			} | ||||
| 		} | ||||
| 		for _, name := range safeTemplate.DNSNames { | ||||
| 			if profile.NameWhitelist.Find([]byte(name)) == nil { | ||||
| 				return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) | ||||
| 			} | ||||
| 		} | ||||
| 		for _, name := range safeTemplate.EmailAddresses { | ||||
| 			if profile.NameWhitelist.Find([]byte(name)) == nil { | ||||
| 				return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if profile.ClientProvidesSerialNumbers { | ||||
| 		if req.Serial == nil { | ||||
| 			return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial) | ||||
| 		} | ||||
| 		safeTemplate.SerialNumber = req.Serial | ||||
| 	} else { | ||||
| 		// RFC 5280 4.1.2.2: | ||||
| 		// Certificate users MUST be able to handle serialNumber | ||||
| 		// values up to 20 octets.  Conforming CAs MUST NOT use | ||||
| 		// serialNumber values longer than 20 octets. | ||||
| 		// | ||||
| 		// If CFSSL is providing the serial numbers, it makes | ||||
| 		// sense to use the max supported size. | ||||
| 		serialNumber := make([]byte, 20) | ||||
| 		_, err = io.ReadFull(rand.Reader, serialNumber) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) | ||||
| 		} | ||||
|  | ||||
| 		// SetBytes interprets buf as the bytes of a big-endian | ||||
| 		// unsigned integer. The leading byte should be masked | ||||
| 		// off to ensure it isn't negative. | ||||
| 		serialNumber[0] &= 0x7F | ||||
|  | ||||
| 		safeTemplate.SerialNumber = new(big.Int).SetBytes(serialNumber) | ||||
| 	} | ||||
|  | ||||
| 	if len(req.Extensions) > 0 { | ||||
| 		for _, ext := range req.Extensions { | ||||
| 			oid := asn1.ObjectIdentifier(ext.ID) | ||||
| 			if !profile.ExtensionWhitelist[oid.String()] { | ||||
| 				return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) | ||||
| 			} | ||||
|  | ||||
| 			rawValue, err := hex.DecodeString(ext.Value) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CertificateError, cferr.InvalidRequest, err) | ||||
| 			} | ||||
|  | ||||
| 			safeTemplate.ExtraExtensions = append(safeTemplate.ExtraExtensions, pkix.Extension{ | ||||
| 				Id:       oid, | ||||
| 				Critical: ext.Critical, | ||||
| 				Value:    rawValue, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var distPoints = safeTemplate.CRLDistributionPoints | ||||
| 	err = signer.FillTemplate(&safeTemplate, s.policy.Default, profile, req.NotBefore, req.NotAfter) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if distPoints != nil && len(distPoints) > 0 { | ||||
| 		safeTemplate.CRLDistributionPoints = distPoints | ||||
| 	} | ||||
|  | ||||
| 	var certTBS = safeTemplate | ||||
|  | ||||
| 	if len(profile.CTLogServers) > 0 || req.ReturnPrecert { | ||||
| 		// Add a poison extension which prevents validation | ||||
| 		var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}} | ||||
| 		var poisonedPreCert = certTBS | ||||
| 		poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension) | ||||
| 		cert, err = s.sign(&poisonedPreCert) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if req.ReturnPrecert { | ||||
| 			return cert, nil | ||||
| 		} | ||||
|  | ||||
| 		derCert, _ := pem.Decode(cert) | ||||
| 		prechain := []ct.ASN1Cert{{Data: derCert.Bytes}, {Data: s.ca.Raw}} | ||||
| 		var sctList []ct.SignedCertificateTimestamp | ||||
|  | ||||
| 		for _, server := range profile.CTLogServers { | ||||
| 			log.Infof("submitting poisoned precertificate to %s", server) | ||||
| 			ctclient, err := client.New(server, nil, jsonclient.Options{}) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CTError, cferr.PrecertSubmissionFailed, err) | ||||
| 			} | ||||
| 			var resp *ct.SignedCertificateTimestamp | ||||
| 			ctx := context.Background() | ||||
| 			resp, err = ctclient.AddPreChain(ctx, prechain) | ||||
| 			if err != nil { | ||||
| 				return nil, cferr.Wrap(cferr.CTError, cferr.PrecertSubmissionFailed, err) | ||||
| 			} | ||||
| 			sctList = append(sctList, *resp) | ||||
| 		} | ||||
|  | ||||
| 		var serializedSCTList []byte | ||||
| 		serializedSCTList, err = helpers.SerializeSCTList(sctList) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) | ||||
| 		} | ||||
|  | ||||
| 		// Serialize again as an octet string before embedding | ||||
| 		serializedSCTList, err = asn1.Marshal(serializedSCTList) | ||||
| 		if err != nil { | ||||
| 			return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) | ||||
| 		} | ||||
|  | ||||
| 		var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList} | ||||
| 		certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension) | ||||
| 	} | ||||
| 	var signedCert []byte | ||||
| 	signedCert, err = s.sign(&certTBS) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Get the AKI from signedCert.  This is required to support Go 1.9+. | ||||
| 	// In prior versions of Go, x509.CreateCertificate updated the | ||||
| 	// AuthorityKeyId of certTBS. | ||||
| 	parsedCert, _ := helpers.ParseCertificatePEM(signedCert) | ||||
|  | ||||
| 	if s.dbAccessor != nil { | ||||
| 		var certRecord = certdb.CertificateRecord{ | ||||
| 			Serial: certTBS.SerialNumber.String(), | ||||
| 			// this relies on the specific behavior of x509.CreateCertificate | ||||
| 			// which sets the AuthorityKeyId from the signer's SubjectKeyId | ||||
| 			AKI:     hex.EncodeToString(parsedCert.AuthorityKeyId), | ||||
| 			CALabel: req.Label, | ||||
| 			Status:  "good", | ||||
| 			Expiry:  certTBS.NotAfter, | ||||
| 			PEM:     string(signedCert), | ||||
| 		} | ||||
|  | ||||
| 		err = s.dbAccessor.InsertCertificate(certRecord) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		log.Debug("saved certificate with serial number ", certTBS.SerialNumber) | ||||
| 	} | ||||
|  | ||||
| 	return signedCert, nil | ||||
| } | ||||
|  | ||||
| // SignFromPrecert creates and signs a certificate from an existing precertificate | ||||
| // that was previously signed by Signer.ca and inserts the provided SCTs into the | ||||
| // new certificate. The resulting certificate will be a exact copy of the precert | ||||
| // except for the removal of the poison extension and the addition of the SCT list | ||||
| // extension. SignFromPrecert does not verify that the contents of the certificate | ||||
| // still match the signing profile of the signer, it only requires that the precert | ||||
| // was previously signed by the Signers CA. | ||||
| func (s *Signer) SignFromPrecert(precert *x509.Certificate, scts []ct.SignedCertificateTimestamp) ([]byte, error) { | ||||
| 	// Verify certificate was signed by s.ca | ||||
| 	if err := precert.CheckSignatureFrom(s.ca); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Verify certificate is a precert | ||||
| 	isPrecert := false | ||||
| 	poisonIndex := 0 | ||||
| 	for i, ext := range precert.Extensions { | ||||
| 		if ext.Id.Equal(signer.CTPoisonOID) { | ||||
| 			if !ext.Critical { | ||||
| 				return nil, cferr.New(cferr.CTError, cferr.PrecertInvalidPoison) | ||||
| 			} | ||||
| 			// Check extension contains ASN.1 NULL | ||||
| 			if bytes.Compare(ext.Value, []byte{0x05, 0x00}) != 0 { | ||||
| 				return nil, cferr.New(cferr.CTError, cferr.PrecertInvalidPoison) | ||||
| 			} | ||||
| 			isPrecert = true | ||||
| 			poisonIndex = i | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if !isPrecert { | ||||
| 		return nil, cferr.New(cferr.CTError, cferr.PrecertMissingPoison) | ||||
| 	} | ||||
|  | ||||
| 	// Serialize SCTs into list format and create extension | ||||
| 	serializedList, err := helpers.SerializeSCTList(scts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Serialize again as an octet string before embedding | ||||
| 	serializedList, err = asn1.Marshal(serializedList) | ||||
| 	if err != nil { | ||||
| 		return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) | ||||
| 	} | ||||
| 	sctExt := pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedList} | ||||
|  | ||||
| 	// Create the new tbsCert from precert. Do explicit copies of any slices so that we don't | ||||
| 	// use memory that may be altered by us or the caller at a later stage. | ||||
| 	tbsCert := x509.Certificate{ | ||||
| 		SignatureAlgorithm:    precert.SignatureAlgorithm, | ||||
| 		PublicKeyAlgorithm:    precert.PublicKeyAlgorithm, | ||||
| 		PublicKey:             precert.PublicKey, | ||||
| 		Version:               precert.Version, | ||||
| 		SerialNumber:          precert.SerialNumber, | ||||
| 		Issuer:                precert.Issuer, | ||||
| 		Subject:               precert.Subject, | ||||
| 		NotBefore:             precert.NotBefore, | ||||
| 		NotAfter:              precert.NotAfter, | ||||
| 		KeyUsage:              precert.KeyUsage, | ||||
| 		BasicConstraintsValid: precert.BasicConstraintsValid, | ||||
| 		IsCA:                        precert.IsCA, | ||||
| 		MaxPathLen:                  precert.MaxPathLen, | ||||
| 		MaxPathLenZero:              precert.MaxPathLenZero, | ||||
| 		PermittedDNSDomainsCritical: precert.PermittedDNSDomainsCritical, | ||||
| 	} | ||||
| 	if len(precert.Extensions) > 0 { | ||||
| 		tbsCert.ExtraExtensions = make([]pkix.Extension, len(precert.Extensions)) | ||||
| 		copy(tbsCert.ExtraExtensions, precert.Extensions) | ||||
| 	} | ||||
|  | ||||
| 	// Remove the poison extension from ExtraExtensions | ||||
| 	tbsCert.ExtraExtensions = append(tbsCert.ExtraExtensions[:poisonIndex], tbsCert.ExtraExtensions[poisonIndex+1:]...) | ||||
| 	// Insert the SCT list extension | ||||
| 	tbsCert.ExtraExtensions = append(tbsCert.ExtraExtensions, sctExt) | ||||
|  | ||||
| 	// Sign the tbsCert | ||||
| 	return s.sign(&tbsCert) | ||||
| } | ||||
|  | ||||
| // Info return a populated info.Resp struct or an error. | ||||
| func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) { | ||||
| 	cert, err := s.Certificate(req.Label, req.Profile) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	profile, err := signer.Profile(s, req.Profile) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	resp = new(info.Resp) | ||||
| 	if cert.Raw != nil { | ||||
| 		resp.Certificate = string(bytes.TrimSpace(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}))) | ||||
| 	} | ||||
| 	resp.Usage = profile.Usage | ||||
| 	resp.ExpiryString = profile.ExpiryString | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // SigAlgo returns the RSA signer's signature algorithm. | ||||
| func (s *Signer) SigAlgo() x509.SignatureAlgorithm { | ||||
| 	return s.sigAlgo | ||||
| } | ||||
|  | ||||
| // Certificate returns the signer's certificate. | ||||
| func (s *Signer) Certificate(label, profile string) (*x509.Certificate, error) { | ||||
| 	cert := *s.ca | ||||
| 	return &cert, nil | ||||
| } | ||||
|  | ||||
| // SetPolicy sets the signer's signature policy. | ||||
| func (s *Signer) SetPolicy(policy *config.Signing) { | ||||
| 	s.policy = policy | ||||
| } | ||||
|  | ||||
| // SetDBAccessor sets the signers' cert db accessor | ||||
| func (s *Signer) SetDBAccessor(dba certdb.Accessor) { | ||||
| 	s.dbAccessor = dba | ||||
| } | ||||
|  | ||||
| // GetDBAccessor returns the signers' cert db accessor | ||||
| func (s *Signer) GetDBAccessor() certdb.Accessor { | ||||
| 	return s.dbAccessor | ||||
| } | ||||
|  | ||||
| // SetReqModifier does nothing for local | ||||
| func (s *Signer) SetReqModifier(func(*http.Request, []byte)) { | ||||
| 	// noop | ||||
| } | ||||
|  | ||||
| // Policy returns the signer's policy. | ||||
| func (s *Signer) Policy() *config.Signing { | ||||
| 	return s.policy | ||||
| } | ||||
							
								
								
									
										1423
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/local_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1423
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/local_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/build_inter_pathlen_csrs.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/build_inter_pathlen_csrs.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| echo '{ "CN": "Pathlen 0 Issuer", "ca": { "pathlen": 0, "pathlenzero": true } }' | cfssl genkey -initca - | cfssljson -bare inter_pathlen_0 | ||||
| echo '{ "CN": "Pathlen 1 Issuer", "ca": { "pathlen": 1 } }' | cfssl genkey -initca - | cfssljson -bare inter_pathlen_1 | ||||
| echo '{ "CN": "Pathlen Unspecified", "ca": {} }' | cfssl genkey -initca - | cfssljson -bare inter_pathlen_unspecified | ||||
							
								
								
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ca.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIEmzCCA4OgAwIBAgIMAMSvNBgypwaaSQ5iMA0GCSqGSIb3DQEBBQUAMIGMMQsw | ||||
| CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy | ||||
| YW5jaXNjbzETMBEGA1UEChMKQ0ZTU0wgVEVTVDEbMBkGA1UEAxMSQ0ZTU0wgVEVT | ||||
| VCBSb290IENBMR4wHAYJKoZIhvcNAQkBFg90ZXN0QHRlc3QubG9jYWwwHhcNMTIx | ||||
| MjEyMDIxMDMxWhcNMjIxMDIxMDIxMDMxWjCBjDELMAkGA1UEBhMCVVMxEzARBgNV | ||||
| BAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAoT | ||||
| CkNGU1NMIFRFU1QxGzAZBgNVBAMTEkNGU1NMIFRFU1QgUm9vdCBDQTEeMBwGCSqG | ||||
| SIb3DQEJARYPdGVzdEB0ZXN0LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A | ||||
| MIIBCgKCAQEAsRp1xSfIDoD/40Bo4Hls3sFn4dav5NgxbZGpVyGF7dJI9u0eEnL4 | ||||
| BUGssPaUFLWC83CZxujUEiEfE0oKX+uOhhGv3+j5xSTNM764m2eSiN53cdZtK05d | ||||
| hwq9uS8LtjKOQeN1mQ5qmiqxBMdjkKgMsVw5lMCgoYKo57kaKFyXzdpNVDzqw+pt | ||||
| HWmuNtDQjK3qT5Ma06mYPmIGYhIZYLY7oJGg9ZEaNR0GIw4zIT5JRsNiaSb5wTLw | ||||
| aa0n/4vLJyVjLJcYmJBvZWj8g+taK+C4INu/jGux+bmsC9hq14tbOaTNAn/NE0qN | ||||
| 8oHwcRBEqfOdEYdZkxI5NWPiKNW/Q+AeXQIDAQABo4H6MIH3MB0GA1UdDgQWBBS3 | ||||
| 0veEuqg51fusEM4p/YuWpBPsvTCBxAYDVR0jBIG8MIG5gBS30veEuqg51fusEM4p | ||||
| /YuWpBPsvaGBkqSBjzCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju | ||||
| aWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAoTCkNGU1NMIFRFU1Qx | ||||
| GzAZBgNVBAMTEkNGU1NMIFRFU1QgUm9vdCBDQTEeMBwGCSqGSIb3DQEJARYPdGVz | ||||
| dEB0ZXN0LmxvY2FsggwAxK80GDKnBppJDmIwDwYDVR0TBAgwBgEB/wIBADANBgkq | ||||
| hkiG9w0BAQUFAAOCAQEAJ7r1EZYDwed6rS0+YKHdkRGRQ5Rz6A9DIVBPXrSMAGj3 | ||||
| F5EF2m/GJbhpVbnNJTVlgP9DDyabOZNxzdrCr4cHMkYYnocDdgAodnkw6GZ/GJTc | ||||
| depbVTR4TpihFNzeDEGJePrEwM1DouGswpu97jyuCYZ3z1a60+a+3C1GwWaJ7Aet | ||||
| Uqm+yLTUrMISsfnDPqJdM1NeqW3jiZ4IgcqJkieCCSpag9Xuzrp9q6rjmePvlQkv | ||||
| qz020JGg6VijJ+c6Tf5y0XqbAhkBTqYtVamu9gEth9utn12EhdNjTZMPKMjjgFUd | ||||
| H0N6yOEuQMl4ky7RxZBM0iPyeob6i4z2LEQilgv9MQ== | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ca_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ca_key.pem
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| -----BEGIN PRIVATE KEY----- | ||||
| MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxGnXFJ8gOgP/j | ||||
| QGjgeWzewWfh1q/k2DFtkalXIYXt0kj27R4ScvgFQayw9pQUtYLzcJnG6NQSIR8T | ||||
| Sgpf646GEa/f6PnFJM0zvribZ5KI3ndx1m0rTl2HCr25Lwu2Mo5B43WZDmqaKrEE | ||||
| x2OQqAyxXDmUwKChgqjnuRooXJfN2k1UPOrD6m0daa420NCMrepPkxrTqZg+YgZi | ||||
| EhlgtjugkaD1kRo1HQYjDjMhPklGw2JpJvnBMvBprSf/i8snJWMslxiYkG9laPyD | ||||
| 61or4Lgg27+Ma7H5uawL2GrXi1s5pM0Cf80TSo3ygfBxEESp850Rh1mTEjk1Y+Io | ||||
| 1b9D4B5dAgMBAAECggEAKHhjcSomDSptTwDo9mLI/h40HudwSlsc8GzYxZBjinUD | ||||
| N2n39T9QbeMUE1xFenX/9qFEgq+xxnLLJx1EQacSapCgIAqdCO/f9HMgvGJumdg8 | ||||
| c0cMq1i9Bp7tu+OESZ5D48qWlOM2eQRIb08g8W11eRIaFmPuUPoKnuktkQuXpPJc | ||||
| YbS/+JuA8SDwe6sV0cMCQuS+iHFfeGwWCKrDUkhLwcL3waW3od2XFyOeFFWFhl0h | ||||
| HmM/mWKRuRdqR7hrmArTwFZVkB+o/1ywVYXIv+JQm0eNZ5PKLNJGL2f5oxbMR/JI | ||||
| AoK0bAlJmYaFp96h1KpbPwLEL/0hHSWA7sAyJIgQAQKBgQDaEAZor/w4ZUTekT1+ | ||||
| cbId0yA+ikDXQOfXaNCSh9Pex+Psjd5zVVOqyVFJ29daRju3d7rmpN4Cm5V4h0l1 | ||||
| /2ad207rjCAnpCHtaddJWNyJzF2IL2IaoCZQRp0k7zOjBGQpoWDTwBaEin5CCv3P | ||||
| kkdQkKz6FDP1xskHSLZr21/QCQKBgQDP6jXutEgGjf3yKpMFk/69EamJdon8clbt | ||||
| hl7cOyWtobnZhdOWVZPe00Oo3Jag2aWgFFsm3EtwnUCnR4d4+fXRKS2LkhfIUZcz | ||||
| cKy17Ileggdd8UGhL4RDrF/En9tJL86WcVkcoOrqLcGB2FLWrVhVpHFK74eLMCH/ | ||||
| uc/+ioPItQKBgHYoDsD08s7AGMQcoNx90MyWVLduhFnegoFW+wUa8jOZzieka6/E | ||||
| wVQeR5yksZjpy3vLNYu6M83n7eLkM2rrm/fXGHlLcTTpm7SgEBZfPwivotKjEh5p | ||||
| PrlqucWEk082lutz1RqHz+u7e1Rfzk2F7nx6GDBdeBYpw03eGXJx6QW5AoGBAIJq | ||||
| 4puyAEAET1fZNtHX7IGCk7sDXTi6LCbgE57HhzHr8V0t4fQ6CABMuvMwM1gATjEk | ||||
| s6yjoLqqGUUUzDipanViBAy5fiuManC868lN7zkWDTLzQ3ytBqVAee4na/DziP27 | ||||
| ae9YTSLJwskE/alloLRP6zTbHUXE0n7LelmrX1DFAoGBAMFLl+Lu+WFgCHxBjn43 | ||||
| rHpJbQZQmsFhAMhkN4hsj6dJfAGn2gRLRiVRAika+8QF65xMZiVQWUVSUZADWERi | ||||
| 0SXGjzN1wYxO3Qzy3LYwws6fxFAq5lo79eb38yFT2lHdqK3x/QgiDSRVl+R6cExV | ||||
| xQB518/lp2eIeMpglWByDwJX | ||||
| -----END PRIVATE KEY----- | ||||
							
								
								
									
										10
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ecdsa256-inter.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ecdsa256-inter.csr
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| -----BEGIN CERTIFICATE REQUEST----- | ||||
| MIIBezCCASECAQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl | ||||
| MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh | ||||
| bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMR0wGwYDVQQDExRjbG91ZGZsYXJl | ||||
| LWludGVyLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLgOKlWwIAIeURde | ||||
| yvDMhgfn6xPp1gn8oUeLmsniBm7I+j84IsVzUso8/MpjMZ9nB8lQUanhv3Kmqcyj | ||||
| HNj+iFegMjAwBgkqhkiG9w0BCQ4xIzAhMB8GA1UdEQQYMBaCFGNsb3VkZmxhcmUt | ||||
| aW50ZXIuY29tMAoGCCqGSM49BAMCA0gAMEUCIEJcy2mn2YyK8lVE+HHmr2OsmdbH | ||||
| 4CLDVXFBwxke8ObqAiEAx/il1cDKvQ/I36b4XjBnOX2jcQ5oaCNPFFBE74WQ/ps= | ||||
| -----END CERTIFICATE REQUEST----- | ||||
							
								
								
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ecdsa256-inter.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/cloudflare/cfssl/signer/local/testdata/ecdsa256-inter.key
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| -----BEGIN EC PRIVATE KEY----- | ||||
| MHcCAQEEILbwI4u4bw+HtafMqFnrL7LOrqNEZH5rW5ygSrigfrVLoAoGCCqGSM49 | ||||
| AwEHoUQDQgAEuA4qVbAgAh5RF17K8MyGB+frE+nWCfyhR4uayeIGbsj6PzgixXNS | ||||
| yjz8ymMxn2cHyVBRqeG/cqapzKMc2P6IVw== | ||||
| -----END EC PRIVATE KEY----- | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user