Allow reading ECDSA key files containing parameter blocks
This commit is contained in:
		| @@ -73,11 +73,25 @@ func ReadPrivateKey(file string) (interface{}, error) { | |||||||
|  |  | ||||||
| // ReadPrivateKeyFromPEM is a helper function for reading a private key from a PEM-encoded file | // ReadPrivateKeyFromPEM is a helper function for reading a private key from a PEM-encoded file | ||||||
| func ReadPrivateKeyFromPEM(data []byte) (interface{}, error) { | func ReadPrivateKeyFromPEM(data []byte) (interface{}, error) { | ||||||
| 	if key, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil { | 	var block *pem.Block | ||||||
| 		return key, nil | 	for { | ||||||
| 	} | 		// read the next block | ||||||
| 	if key, err := jwt.ParseECPrivateKeyFromPEM(data); err == nil { | 		block, data = pem.Decode(data) | ||||||
| 		return key, nil | 		if block == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// get PEM bytes for just this block | ||||||
|  | 		blockData := pem.EncodeToMemory(block) | ||||||
|  | 		if key, err := jwt.ParseRSAPrivateKeyFromPEM(blockData); err == nil { | ||||||
|  | 			return key, nil | ||||||
|  | 		} | ||||||
|  | 		if key, err := jwt.ParseECPrivateKeyFromPEM(blockData); err == nil { | ||||||
|  | 			return key, nil | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// tolerate non-key PEM blocks for compatibility with things like "EC PARAMETERS" blocks | ||||||
|  | 		// originally, only the first PEM block was parsed and expected to be a key block | ||||||
| 	} | 	} | ||||||
| 	return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key") | 	return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key") | ||||||
| } | } | ||||||
|   | |||||||
| @@ -81,6 +81,17 @@ X024wzbiw1q07jFCyfQmODzURAx1VNT7QVUMdz/N8vy47/H40AZJ | |||||||
| -----END RSA PRIVATE KEY----- | -----END RSA PRIVATE KEY----- | ||||||
| ` | ` | ||||||
|  |  | ||||||
|  | // openssl ecparam -name prime256v1 -genkey -out ecdsa256params.pem | ||||||
|  | const ecdsaPrivateKeyWithParams = `-----BEGIN EC PARAMETERS----- | ||||||
|  | BggqhkjOPQMBBw== | ||||||
|  | -----END EC PARAMETERS----- | ||||||
|  | -----BEGIN EC PRIVATE KEY----- | ||||||
|  | MHcCAQEEIJ9LWDj3ZWe9CksPV7mZjD2dYXG9icfzxadCRwd3vr1toAoGCCqGSM49 | ||||||
|  | AwEHoUQDQgAEaLNEpzbaaNTCkKjBVj7sxpfJ1ifJQGNvcck4nrzcwFRuujwVDDJh | ||||||
|  | 95iIGwKCQeSg+yhdN6Q/p2XaxNIZlYmUhg== | ||||||
|  | -----END EC PRIVATE KEY----- | ||||||
|  | ` | ||||||
|  |  | ||||||
| // openssl ecparam -name prime256v1 -genkey -noout -out ecdsa256.pem | // openssl ecparam -name prime256v1 -genkey -noout -out ecdsa256.pem | ||||||
| const ecdsaPrivateKey = `-----BEGIN EC PRIVATE KEY----- | const ecdsaPrivateKey = `-----BEGIN EC PRIVATE KEY----- | ||||||
| MHcCAQEEIEZmTmUhuanLjPA2CLquXivuwBDHTt5XYwgIr/kA1LtRoAoGCCqGSM49 | MHcCAQEEIEZmTmUhuanLjPA2CLquXivuwBDHTt5XYwgIr/kA1LtRoAoGCCqGSM49 | ||||||
| @@ -110,6 +121,10 @@ func TestReadPrivateKey(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	defer os.Remove(f.Name()) | 	defer os.Remove(f.Name()) | ||||||
|  |  | ||||||
|  | 	if _, err := serviceaccount.ReadPrivateKey(f.Name()); err == nil { | ||||||
|  | 		t.Fatalf("Expected error reading key from empty file, got none") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err := ioutil.WriteFile(f.Name(), []byte(rsaPrivateKey), os.FileMode(0600)); err != nil { | 	if err := ioutil.WriteFile(f.Name(), []byte(rsaPrivateKey), os.FileMode(0600)); err != nil { | ||||||
| 		t.Fatalf("error writing private key to tmpfile: %v", err) | 		t.Fatalf("error writing private key to tmpfile: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -123,6 +138,13 @@ func TestReadPrivateKey(t *testing.T) { | |||||||
| 	if _, err := serviceaccount.ReadPrivateKey(f.Name()); err != nil { | 	if _, err := serviceaccount.ReadPrivateKey(f.Name()); err != nil { | ||||||
| 		t.Fatalf("error reading private ECDSA key: %v", err) | 		t.Fatalf("error reading private ECDSA key: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if err := ioutil.WriteFile(f.Name(), []byte(ecdsaPrivateKeyWithParams), os.FileMode(0600)); err != nil { | ||||||
|  | 		t.Fatalf("error writing private key to tmpfile: %v", err) | ||||||
|  | 	} | ||||||
|  | 	if _, err := serviceaccount.ReadPrivateKey(f.Name()); err != nil { | ||||||
|  | 		t.Fatalf("error reading private ECDSA key with params: %v", err) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestReadPublicKeys(t *testing.T) { | func TestReadPublicKeys(t *testing.T) { | ||||||
| @@ -132,6 +154,10 @@ func TestReadPublicKeys(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	defer os.Remove(f.Name()) | 	defer os.Remove(f.Name()) | ||||||
|  |  | ||||||
|  | 	if _, err := serviceaccount.ReadPublicKeys(f.Name()); err == nil { | ||||||
|  | 		t.Fatalf("Expected error reading keys from empty file, got none") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err := ioutil.WriteFile(f.Name(), []byte(rsaPublicKey), os.FileMode(0600)); err != nil { | 	if err := ioutil.WriteFile(f.Name(), []byte(rsaPublicKey), os.FileMode(0600)); err != nil { | ||||||
| 		t.Fatalf("error writing public key to tmpfile: %v", err) | 		t.Fatalf("error writing public key to tmpfile: %v", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jordan Liggitt
					Jordan Liggitt