fix(cmds/keystore): do not allow to import keys we don't generate (#8733)
Lucas Molas committed
Feb 18, 2022 at 19:42 UTC
3ea5631f9a0da288882b12189ebae3eca5e941ec
4 files changed
+52
core/commands/keystore.go
+16
@@ -143,6 +143,7 @@ const (
143
keyFormatOptionName = "format"
144
keyFormatPemCleartextOption = "pem-pkcs8-cleartext"
145
keyFormatLibp2pCleartextOption = "libp2p-protobuf-cleartext"
146
+ keyAllowAnyTypeOptionName = "allow-any-key-type"
147
)
148
149
var keyExportCmd = &cmds.Command{
@@ -319,6 +320,7 @@ The PEM format allows for key generation outside of the IPFS node:
320
Options: []cmds.Option{
321
ke.OptionIPNSBase,
322
cmds.StringOption(keyFormatOptionName, "f", "The format of the private key to import, libp2p-protobuf-cleartext or pem-pkcs8-cleartext.").WithDefault(keyFormatLibp2pCleartextOption),
323
+ cmds.BoolOption(keyAllowAnyTypeOptionName, "Allow importing any key type.").WithDefault(false),
324
},
325
Arguments: []cmds.Argument{
326
cmds.StringArg("name", true, false, "name to associate with key in keychain"),
@@ -391,6 +393,20 @@ The PEM format allows for key generation outside of the IPFS node:
393
return fmt.Errorf("unrecognized import format: %s", importFormat)
394
}
395
396
+ // We only allow importing keys of the same type we generate (see list in
397
+ // https://github.com/ipfs/interface-go-ipfs-core/blob/1c3d8fc/options/key.go#L58-L60),
398
+ // unless explicitly stated by the user.
399
+ allowAnyKeyType, _ := req.Options[keyAllowAnyTypeOptionName].(bool)
400
+ if !allowAnyKeyType {
401
+ switch t := sk.(type) {
402
+ case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey:
403
+ default:
404
+ return fmt.Errorf("key type %T is not allowed to be imported, only RSA or Ed25519;"+
405
+ " use flag --%s if you are sure of what you're doing",
406
+ t, keyAllowAnyTypeOptionName)
407
+ }
408
+ }
409
+
410
cfgRoot, err := cmdenv.GetConfigRoot(env)
411
if err != nil {
412
return err
test/sharness/t0165-keystore-data/README.md
+18
@@ -6,3 +6,21 @@ Created with commands:
6
openssl genpkey -algorithm ED25519 > openssl_ed25519.pem
7
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 > openssl_rsa.pem
8
```
9
+
10
+secp key used in the 'restrict import key' test.
11
+From: https://www.openssl.org/docs/man1.1.1/man1/openssl-genpkey.html
12
+```bash
13
+openssl genpkey -genparam -algorithm EC -out ecp.pem \
14
+ -pkeyopt ec_paramgen_curve:secp384r1 \
15
+ -pkeyopt ec_param_enc:named_curve
16
+openssl genpkey -paramfile ecp.pem -out openssl_secp384r1.pem
17
+rm ecp.pem
18
+```
19
+Note: The Bitcoin `secp256k1` curve which is what `go-libp2p-core/crypto`
20
+actually generates and would be of interest to test against is not
21
+recognized by the Go library:
22
+```
23
+Error: parsing PKCS8 format: x509: failed to parse EC private key embedded
24
+ in PKCS#8: x509: unknown elliptic curve
25
+```
26
+We keep the `secp384r1` type instead from the original openssl example.
test/sharness/t0165-keystore-data/openssl_secp384r1.pem
new
+6
@@ -0,0 +1,6 @@
1
+-----BEGIN PRIVATE KEY-----
2
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8DksLZwPKGQS8tuWI
3
+w+dNYiSHUyw30NkrK9YGmjgp84sVVa5NGrv0QniAnNWG1DqhZANiAATq0d5KV1MF
4
+IIpF4beNX+YsmFdqB2oDLhznO/4xNsFCFKE39oGQmuMwnQhDNZZ2CQA8csfgZmuF
5
+OSooe/Ru6ubyeGVKafcHJrOMBvl8hIg0tVWgIAhuXiTHq0UL0QTv9Vk=
6
+-----END PRIVATE KEY-----
test/sharness/t0165-keystore.sh
+12
@@ -74,6 +74,18 @@ ipfs key rm key_ed25519
74
75
test_openssl_compatibility_all_types
76
77
+ INVALID_KEY=../t0165-keystore-data/openssl_secp384r1.pem
78
+ test_expect_success "import key type we don't generate fails" '
79
+ test_must_fail ipfs key import restricted-type -f pem-pkcs8-cleartext $INVALID_KEY 2>&1 | tee key_exp_out &&
80
+ grep -q "Error: key type \*crypto.ECDSAPrivateKey is not allowed to be imported" key_exp_out &&
81
+ rm key_exp_out
82
+ '
83
+
84
+ test_expect_success "import key type we don't generate succeeds with flag" '
85
+ ipfs key import restricted-type --allow-any-key-type -f pem-pkcs8-cleartext $INVALID_KEY > /dev/null &&
86
+ ipfs key rm restricted-type
87
+ '
88
+
89
test_expect_success "test export file option" '
90
ipfs key export generated_rsa_key -o=named_rsa_export_file &&
91
test_cmp generated_rsa_key.key named_rsa_export_file &&