mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	*Partially* revert "Remove now-unneeded PKCS8 code and update certutil tests for Go 1.10"
This partially reverts commit 83f6b21d3e.
			
			
This commit is contained in:
		| @@ -1351,7 +1351,7 @@ func convertRespToPKCS8(resp *logical.Response) error { | ||||
| 		return errwrap.Wrapf("error converting response to pkcs8: error parsing previous key: {{err}}", err) | ||||
| 	} | ||||
|  | ||||
| 	keyData, err = x509.MarshalPKCS8PrivateKey(signer) | ||||
| 	keyData, err = certutil.MarshalPKCS8PrivateKey(signer) | ||||
| 	if err != nil { | ||||
| 		return errwrap.Wrapf("error converting response to pkcs8: error marshaling pkcs8 key: {{err}}", err) | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										119
									
								
								helper/certutil/pkcs8.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								helper/certutil/pkcs8.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package certutil | ||||
|  | ||||
| import ( | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"crypto/x509/pkix" | ||||
| 	"encoding/asn1" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} | ||||
| 	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} | ||||
| 	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} | ||||
| 	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} | ||||
|  | ||||
| 	oidPublicKeyRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} | ||||
| 	oidPublicKeyDSA   = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} | ||||
| 	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} | ||||
| ) | ||||
|  | ||||
| // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See | ||||
| // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn | ||||
| // and RFC 5208. | ||||
| type pkcs8 struct { | ||||
| 	Version    int | ||||
| 	Algo       pkix.AlgorithmIdentifier | ||||
| 	PrivateKey []byte | ||||
| 	// optional attributes omitted. | ||||
| } | ||||
|  | ||||
| type ecPrivateKey struct { | ||||
| 	Version       int | ||||
| 	PrivateKey    []byte | ||||
| 	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` | ||||
| 	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"` | ||||
| } | ||||
|  | ||||
| // MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form. | ||||
| // The following key types are supported: *rsa.PrivateKey, *ecdsa.PublicKey. | ||||
| // Unsupported key types result in an error. | ||||
| // | ||||
| // See RFC 5208. | ||||
| func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) { | ||||
| 	var privKey pkcs8 | ||||
|  | ||||
| 	switch k := key.(type) { | ||||
| 	case *rsa.PrivateKey: | ||||
| 		privKey.Algo = pkix.AlgorithmIdentifier{ | ||||
| 			Algorithm:  oidPublicKeyRSA, | ||||
| 			Parameters: asn1.NullRawValue, | ||||
| 		} | ||||
| 		privKey.PrivateKey = x509.MarshalPKCS1PrivateKey(k) | ||||
|  | ||||
| 	case *ecdsa.PrivateKey: | ||||
| 		oid, ok := oidFromNamedCurve(k.Curve) | ||||
| 		if !ok { | ||||
| 			return nil, errors.New("x509: unknown curve while marshalling to PKCS#8") | ||||
| 		} | ||||
|  | ||||
| 		oidBytes, err := asn1.Marshal(oid) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) | ||||
| 		} | ||||
|  | ||||
| 		privKey.Algo = pkix.AlgorithmIdentifier{ | ||||
| 			Algorithm: oidPublicKeyECDSA, | ||||
| 			Parameters: asn1.RawValue{ | ||||
| 				FullBytes: oidBytes, | ||||
| 			}, | ||||
| 		} | ||||
|  | ||||
| 		if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { | ||||
| 			return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key) | ||||
| 	} | ||||
|  | ||||
| 	return asn1.Marshal(privKey) | ||||
| } | ||||
|  | ||||
| func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { | ||||
| 	switch curve { | ||||
| 	case elliptic.P224(): | ||||
| 		return oidNamedCurveP224, true | ||||
| 	case elliptic.P256(): | ||||
| 		return oidNamedCurveP256, true | ||||
| 	case elliptic.P384(): | ||||
| 		return oidNamedCurveP384, true | ||||
| 	case elliptic.P521(): | ||||
| 		return oidNamedCurveP521, true | ||||
| 	} | ||||
|  | ||||
| 	return nil, false | ||||
| } | ||||
|  | ||||
| // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and | ||||
| // sets the curve ID to the given OID, or omits it if OID is nil. | ||||
| func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) { | ||||
| 	privateKeyBytes := key.D.Bytes() | ||||
| 	paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) | ||||
| 	copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) | ||||
|  | ||||
| 	return asn1.Marshal(ecPrivateKey{ | ||||
| 		Version:       1, | ||||
| 		PrivateKey:    paddedPrivateKey, | ||||
| 		NamedCurveOID: oid, | ||||
| 		PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										110
									
								
								helper/certutil/pkcs8_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								helper/certutil/pkcs8_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package certutil | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/hex" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| // Generated using: | ||||
| //   openssl genrsa 1024 | openssl pkcs8 -topk8 -nocrypt | ||||
| var pkcs8RSAPrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031` | ||||
|  | ||||
| // Generated using: | ||||
| //   openssl ecparam -genkey -name secp224r1 | openssl pkcs8 -topk8 -nocrypt | ||||
| var pkcs8P224PrivateKeyHex = `3078020100301006072a8648ce3d020106052b810400210461305f020101041cca3d72b3e88fed2684576dad9b80a9180363a5424986900e3abcab3fa13c033a0004f8f2a6372872a4e61263ed893afb919576a4cacfecd6c081a2cbc76873cf4ba8530703c6042b3a00e2205087e87d2435d2e339e25702fae1` | ||||
|  | ||||
| // Generated using: | ||||
| //   openssl ecparam -genkey -name secp256r1 | openssl pkcs8 -topk8 -nocrypt | ||||
| var pkcs8P256PrivateKeyHex = `308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420dad6b2f49ca774c36d8ae9517e935226f667c929498f0343d2424d0b9b591b43a14403420004b9c9b90095476afe7b860d8bd43568cab7bcb2eed7b8bf2fa0ce1762dd20b04193f859d2d782b1e4cbfd48492f1f533113a6804903f292258513837f07fda735` | ||||
|  | ||||
| // Generated using: | ||||
| //   openssl ecparam -genkey -name secp384r1 | openssl pkcs8 -topk8 -nocrypt | ||||
| var pkcs8P384PrivateKeyHex = `3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104309bf832f6aaaeacb78ce47ffb15e6fd0fd48683ae79df6eca39bfb8e33829ac94aa29d08911568684c2264a08a4ceb679a164036200049070ad4ed993c7770d700e9f6dc2baa83f63dd165b5507f98e8ff29b5d2e78ccbe05c8ddc955dbf0f7497e8222cfa49314fe4e269459f8e880147f70d785e530f2939e4bf9f838325bb1a80ad4cf59272ae0e5efe9a9dc33d874492596304bd3` | ||||
|  | ||||
| // Generated using: | ||||
| //   openssl ecparam -genkey -name secp521r1 | openssl pkcs8 -topk8 -nocrypt | ||||
| // | ||||
| // Note that OpenSSL will truncate the private key if it can (i.e. it emits it | ||||
| // like an integer, even though it's an OCTET STRING field). Thus if you | ||||
| // regenerate this you may, randomly, find that it's a byte shorter than | ||||
| // expected and the Go test will fail to recreate it exactly. | ||||
| var pkcs8P521PrivateKeyHex = `3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044200cfe0b87113a205cf291bb9a8cd1a74ac6c7b2ebb8199aaa9a5010d8b8012276fa3c22ac913369fa61beec2a3b8b4516bc049bde4fb3b745ac11b56ab23ac52e361a1818903818600040138f75acdd03fbafa4f047a8e4b272ba9d555c667962b76f6f232911a5786a0964e5edea6bd21a6f8725720958de049c6e3e6661c1c91b227cebee916c0319ed6ca003db0a3206d372229baf9dd25d868bf81140a518114803ce40c1855074d68c4e9dab9e65efba7064c703b400f1767f217dac82715ac1f6d88c74baf47a7971de4ea` | ||||
|  | ||||
| func TestPKCS8(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| 		keyHex  string | ||||
| 		keyType reflect.Type | ||||
| 		curve   elliptic.Curve | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:    "RSA private key", | ||||
| 			keyHex:  pkcs8RSAPrivateKeyHex, | ||||
| 			keyType: reflect.TypeOf(&rsa.PrivateKey{}), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "P-224 private key", | ||||
| 			keyHex:  pkcs8P224PrivateKeyHex, | ||||
| 			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}), | ||||
| 			curve:   elliptic.P224(), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "P-256 private key", | ||||
| 			keyHex:  pkcs8P256PrivateKeyHex, | ||||
| 			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}), | ||||
| 			curve:   elliptic.P256(), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "P-384 private key", | ||||
| 			keyHex:  pkcs8P384PrivateKeyHex, | ||||
| 			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}), | ||||
| 			curve:   elliptic.P384(), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "P-521 private key", | ||||
| 			keyHex:  pkcs8P521PrivateKeyHex, | ||||
| 			keyType: reflect.TypeOf(&ecdsa.PrivateKey{}), | ||||
| 			curve:   elliptic.P521(), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, test := range tests { | ||||
| 		derBytes, err := hex.DecodeString(test.keyHex) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("%s: failed to decode hex: %s", test.name, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		privKey, err := x509.ParsePKCS8PrivateKey(derBytes) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("%s: failed to decode PKCS#8: %s", test.name, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		if reflect.TypeOf(privKey) != test.keyType { | ||||
| 			t.Errorf("%s: decoded PKCS#8 returned unexpected key type: %T", test.name, privKey) | ||||
| 			continue | ||||
| 		} | ||||
| 		if ecKey, isEC := privKey.(*ecdsa.PrivateKey); isEC && ecKey.Curve != test.curve { | ||||
| 			t.Errorf("%s: decoded PKCS#8 returned unexpected curve %#v", test.name, ecKey.Curve) | ||||
| 			continue | ||||
| 		} | ||||
| 		reserialised, err := MarshalPKCS8PrivateKey(privKey) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("%s: failed to marshal into PKCS#8: %s", test.name, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		if !bytes.Equal(derBytes, reserialised) { | ||||
| 			t.Errorf("%s: marshalled PKCS#8 didn't match original: got %x, want %x", test.name, reserialised, derBytes) | ||||
| 			continue | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -49,25 +49,25 @@ func FetchKeybasePubkeys(input []string) (map[string]string, error) { | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	type PublicKeys struct { | ||||
| 	type publicKeys struct { | ||||
| 		Primary struct { | ||||
| 			Bundle string | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	type LThem struct { | ||||
| 		PublicKeys `json:"public_keys"` | ||||
| 	type them struct { | ||||
| 		publicKeys `json:"public_keys"` | ||||
| 	} | ||||
|  | ||||
| 	type KbResp struct { | ||||
| 	type kbResp struct { | ||||
| 		Status struct { | ||||
| 			Name string | ||||
| 		} | ||||
| 		Them []LThem | ||||
| 		Them []them | ||||
| 	} | ||||
|  | ||||
| 	out := &KbResp{ | ||||
| 		Them: []LThem{}, | ||||
| 	out := &kbResp{ | ||||
| 		Them: []them{}, | ||||
| 	} | ||||
|  | ||||
| 	if err := jsonutil.DecodeJSONFromReader(resp.Body, out); err != nil { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeff Mitchell
					Jeff Mitchell