Merge pull request #7251 from ipfs/feat/ed25519identity

Choose Key type at initialization
This commit is contained in:
Adin Schmahmann 2020-07-14 14:55:48 -04:00 committed by GitHub
commit b98f797bba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 198 additions and 88 deletions

View File

@ -31,6 +31,7 @@ import (
cmds "github.com/ipfs/go-ipfs-cmds"
mprome "github.com/ipfs/go-metrics-prometheus"
options "github.com/ipfs/interface-go-ipfs-core/options"
goprocess "github.com/jbenet/goprocess"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net"
@ -247,7 +248,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
}
}
if err = doInit(os.Stdout, cctx.ConfigRoot, false, nBitsForKeypairDefault, profiles, conf); err != nil {
identity, err := config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
options.Key.Type(algorithmDefault),
})
if err != nil {
return err
}
if err = doInit(os.Stdout, cctx.ConfigRoot, false, &identity, profiles, conf); err != nil {
return err
}
}

View File

@ -19,13 +19,15 @@ import (
cmds "github.com/ipfs/go-ipfs-cmds"
config "github.com/ipfs/go-ipfs-config"
files "github.com/ipfs/go-ipfs-files"
options "github.com/ipfs/interface-go-ipfs-core/options"
)
const (
nBitsForKeypairDefault = 2048
bitsOptionName = "bits"
emptyRepoOptionName = "empty-repo"
profileOptionName = "profile"
algorithmDefault = options.RSAKey
algorithmOptionName = "algorithm"
bitsOptionName = "bits"
emptyRepoOptionName = "empty-repo"
profileOptionName = "profile"
)
var errRepoExists = errors.New(`ipfs configuration file already exists!
@ -54,7 +56,8 @@ environment variable:
cmds.FileArg("default-config", false, false, "Initialize with the given configuration.").EnableStdin(),
},
Options: []cmds.Option{
cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key.").WithDefault(nBitsForKeypairDefault),
cmds.StringOption(algorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(algorithmDefault),
cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key."),
cmds.BoolOption(emptyRepoOptionName, "e", "Don't add and pin help files to the local storage."),
cmds.StringOption(profileOptionName, "p", "Apply profile settings to config. Multiple profiles can be separated by ','"),
@ -82,7 +85,8 @@ environment variable:
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
cctx := env.(*oldcmds.Context)
empty, _ := req.Options[emptyRepoOptionName].(bool)
nBitsForKeypair, _ := req.Options[bitsOptionName].(int)
algorithm, _ := req.Options[algorithmOptionName].(string)
nBitsForKeypair, nBitsGiven := req.Options[bitsOptionName].(int)
var conf *config.Config
@ -106,8 +110,24 @@ environment variable:
}
}
var err error
var identity config.Identity
if nBitsGiven {
identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
options.Key.Size(nBitsForKeypair),
options.Key.Type(algorithm),
})
} else {
identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
options.Key.Type(algorithm),
})
}
if err != nil {
return err
}
profiles, _ := req.Options[profileOptionName].(string)
return doInit(os.Stdout, cctx.ConfigRoot, empty, nBitsForKeypair, profiles, conf)
return doInit(os.Stdout, cctx.ConfigRoot, empty, &identity, profiles, conf)
},
}
@ -129,7 +149,7 @@ func applyProfiles(conf *config.Config, profiles string) error {
return nil
}
func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, confProfiles string, conf *config.Config) error {
func doInit(out io.Writer, repoRoot string, empty bool, identity *config.Identity, confProfiles string, conf *config.Config) error {
if _, err := fmt.Fprintf(out, "initializing IPFS node at %s\n", repoRoot); err != nil {
return err
}
@ -142,9 +162,13 @@ func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, con
return errRepoExists
}
if identity == nil {
return fmt.Errorf("No Identity provided for initialization")
}
if conf == nil {
var err error
conf, err = config.Init(out, nBitsForKeypair)
conf, err = config.InitWithIdentity(*identity)
if err != nil {
return err
}

2
go.mod
View File

@ -32,7 +32,7 @@ require (
github.com/ipfs/go-ipfs-blockstore v0.1.4
github.com/ipfs/go-ipfs-chunker v0.0.5
github.com/ipfs/go-ipfs-cmds v0.2.9
github.com/ipfs/go-ipfs-config v0.8.0
github.com/ipfs/go-ipfs-config v0.9.0
github.com/ipfs/go-ipfs-ds-help v0.1.1
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
github.com/ipfs/go-ipfs-exchange-offline v0.0.1

4
go.sum
View File

@ -346,6 +346,10 @@ github.com/ipfs/go-ipfs-cmds v0.2.9 h1:zQTENe9UJrtCb2bOtRoDGjtuo3rQjmuPdPnVlqoBV
github.com/ipfs/go-ipfs-cmds v0.2.9/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
github.com/ipfs/go-ipfs-config v0.8.0 h1:4Tc7DC3dz4e7VadOjxXxFQGTQ1g7EYZClJ/ih8qOrxE=
github.com/ipfs/go-ipfs-config v0.8.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
github.com/ipfs/go-ipfs-config v0.8.1-0.20200714165010-0b2590596cd4 h1:gD1K9GUACg3QRyjJD5rxTW/dUEYJt2/a98nnCoISSOk=
github.com/ipfs/go-ipfs-config v0.8.1-0.20200714165010-0b2590596cd4/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
github.com/ipfs/go-ipfs-config v0.9.0 h1:qTXJ9CyOyQv1LFJUMysxz8fi6RxxnP9QqcmiobuANvw=
github.com/ipfs/go-ipfs-config v0.9.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=

View File

@ -445,7 +445,7 @@ file_size() {
test_check_peerid() {
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
test "$peeridlen" = "46" || {
test "$peeridlen" = "46" -o "$peeridlen" = "52" -o "$peeridlen" = "62" || {
echo "Bad peerid '$1' with len '$peeridlen'"
return 1
}

View File

@ -50,93 +50,154 @@ test_expect_success "ipfs cat no repo message looks good" '
test_path_cmp cat_fail_exp cat_fail_out
'
# test that init succeeds
test_expect_success "ipfs init succeeds" '
export IPFS_PATH="$(pwd)/.ipfs" &&
echo "IPFS_PATH: \"$IPFS_PATH\"" &&
BITS="2048" &&
ipfs init --bits="$BITS" >actual_init ||
test_fsh cat actual_init
'
# $1 must be one of 'rsa', 'ed25519' or '' (for default key algorithm).
test_ipfs_init_flags() {
TEST_ALG=$1
test_expect_success ".ipfs/ has been created" '
test -d ".ipfs" &&
test -f ".ipfs/config" &&
test -d ".ipfs/datastore" &&
test -d ".ipfs/blocks" &&
test ! -f ._check_writeable ||
test_fsh ls -al .ipfs
'
# test that init succeeds
test_expect_success "ipfs init succeeds" '
export IPFS_PATH="$(pwd)/.ipfs" &&
echo "IPFS_PATH: \"$IPFS_PATH\"" &&
RSA_BITS="2048" &&
case $TEST_ALG in
"rsa")
ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init
;;
"ed25519")
ipfs init --algorithm=ed25519 >actual_init || test_fsh cat actual_init
;;
*)
ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init
;;
esac
'
test_expect_success "ipfs config succeeds" '
echo /ipfs >expected_config &&
ipfs config Mounts.IPFS >actual_config &&
test_cmp expected_config actual_config
'
test_expect_success ".ipfs/ has been created" '
test -d ".ipfs" &&
test -f ".ipfs/config" &&
test -d ".ipfs/datastore" &&
test -d ".ipfs/blocks" &&
test ! -f ._check_writeable ||
test_fsh ls -al .ipfs
'
test_expect_success "ipfs peer id looks good" '
PEERID=$(ipfs config Identity.PeerID) &&
test_check_peerid "$PEERID"
'
test_expect_success "ipfs config succeeds" '
echo /ipfs >expected_config &&
ipfs config Mounts.IPFS >actual_config &&
test_cmp expected_config actual_config
'
test_expect_success "ipfs init output looks good" '
STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" &&
echo "initializing IPFS node at $IPFS_PATH" >expected &&
echo "generating $BITS-bit RSA keypair...done" >>expected &&
echo "peer identity: $PEERID" >>expected &&
echo "to get started, enter:" >>expected &&
printf "\\n\\t$STARTFILE\\n\\n" >>expected &&
test_cmp expected actual_init
'
test_expect_success "ipfs peer id looks good" '
PEERID=$(ipfs config Identity.PeerID) &&
test_check_peerid "$PEERID"
'
test_expect_success "Welcome readme exists" '
ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
'
test_expect_success "ipfs init output looks good" '
STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" &&
test_expect_success "clean up ipfs dir" '
rm -rf "$IPFS_PATH"
'
echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected &&
echo "peer identity: $PEERID" >>rsa_expected &&
echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected &&
echo "to get started, enter:" >>rsa_expected &&
printf "\\n\\t$STARTFILE\\n\\n" >>rsa_expected &&
test_expect_success "'ipfs init --empty-repo' succeeds" '
BITS="2048" &&
ipfs init --bits="$BITS" --empty-repo >actual_init
'
echo "generating ED25519 keypair...done" >ed25519_expected &&
echo "peer identity: $PEERID" >>ed25519_expected &&
echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected &&
echo "to get started, enter:" >>ed25519_expected &&
printf "\\n\\t$STARTFILE\\n\\n" >>ed25519_expected &&
test_expect_success "ipfs peer id looks good" '
PEERID=$(ipfs config Identity.PeerID) &&
test_check_peerid "$PEERID"
'
case $TEST_ALG in
rsa)
test_cmp rsa_expected actual_init
;;
ed25519)
test_cmp ed25519_expected actual_init
;;
*)
test_cmp rsa_expected actual_init
;;
esac
'
test_expect_success "'ipfs init --empty-repo' output looks good" '
echo "initializing IPFS node at $IPFS_PATH" >expected &&
echo "generating $BITS-bit RSA keypair...done" >>expected &&
echo "peer identity: $PEERID" >>expected &&
test_cmp expected actual_init
'
test_expect_success "Welcome readme exists" '
ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
'
test_expect_success "Welcome readme doesn't exist" '
test_must_fail ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
'
test_expect_success "clean up ipfs dir" '
rm -rf "$IPFS_PATH"
'
test_expect_success "ipfs id agent string contains correct version" '
ipfs id -f "<aver>" | grep $(ipfs version -n)
'
test_expect_success "'ipfs init --empty-repo' succeeds" '
RSA_BITS="2048" &&
case $TEST_ALG in
rsa)
ipfs init --algorithm=rsa --bits="$RSA_BITS" --empty-repo >actual_init
;;
ed25519)
ipfs init --algorithm=ed25519 --empty-repo >actual_init
;;
*)
ipfs init --bits="$RSA_BITS" --empty-repo >actual_init
;;
esac
'
test_expect_success "clean up ipfs dir" '
rm -rf "$IPFS_PATH"
'
test_expect_success "ipfs peer id looks good" '
PEERID=$(ipfs config Identity.PeerID) &&
test_check_peerid "$PEERID"
'
test_expect_success "'ipfs init --empty-repo' output looks good" '
echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected &&
echo "peer identity: $PEERID" >>rsa_expected &&
echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected &&
echo "generating ED25519 keypair...done" >ed25519_expected &&
echo "peer identity: $PEERID" >>ed25519_expected &&
echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected &&
case $TEST_ALG in
rsa)
test_cmp rsa_expected actual_init
;;
ed25519)
test_cmp ed25519_expected actual_init
;;
*)
test_cmp rsa_expected actual_init
;;
esac
'
test_expect_success "Welcome readme doesn't exist" '
test_must_fail ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
'
test_expect_success "ipfs id agent string contains correct version" '
ipfs id -f "<aver>" | grep $(ipfs version -n)
'
test_expect_success "clean up ipfs dir" '
rm -rf "$IPFS_PATH"
'
}
test_ipfs_init_flags 'ed25519'
test_ipfs_init_flags 'rsa'
test_ipfs_init_flags ''
# test init profiles
test_expect_success "'ipfs init --profile' with invalid profile fails" '
BITS="2048" &&
test_must_fail ipfs init --bits="$BITS" --profile=nonexistent_profile 2> invalid_profile_out
RSA_BITS="2048" &&
test_must_fail ipfs init --bits="$RSA_BITS" --profile=nonexistent_profile 2> invalid_profile_out
EXPECT="Error: invalid configuration profile: nonexistent_profile" &&
grep "$EXPECT" invalid_profile_out
'
test_expect_success "'ipfs init --profile' succeeds" '
BITS="2048" &&
ipfs init --bits="$BITS" --profile=server
RSA_BITS="2048" &&
ipfs init --bits="$RSA_BITS" --profile=server
'
test_expect_success "'ipfs config Swarm.AddrFilters' looks good" '
@ -149,8 +210,8 @@ test_expect_success "clean up ipfs dir" '
'
test_expect_success "'ipfs init --profile=test' succeeds" '
BITS="2048" &&
ipfs init --bits="$BITS" --profile=test
RSA_BITS="2048" &&
ipfs init --bits="$RSA_BITS" --profile=test
'
test_expect_success "'ipfs config Bootstrap' looks good" '
@ -182,8 +243,8 @@ test_expect_success "clean up ipfs dir" '
'
test_expect_success "'ipfs init --profile=lowpower' succeeds" '
BITS="2048" &&
ipfs init --bits="$BITS" --profile=lowpower
RSA_BITS="2048" &&
ipfs init --bits="$RSA_BITS" --profile=lowpower
'
test_expect_success "'ipfs config Discovery.Routing' looks good" '

View File

@ -94,6 +94,7 @@ test_expect_success "Add test text file" '
CIDv1=$(echo $CID_VAL | ipfs add --cid-version 1 -Q)
CIDv0=$(echo $CID_VAL | ipfs add --cid-version 0 -Q)
CIDv0to1=$(echo "$CIDv0" | ipfs cid base32)
echo CIDv0to1=${CIDv0to1}
'
test_expect_success "Add the test directory" '
@ -107,13 +108,25 @@ test_expect_success "Add the test directory" '
DIR_CID=$(ipfs add -Qr --cid-version 1 testdirlisting)
'
test_expect_success "Publish test text file to IPNS" '
PEERID=$(ipfs id --format="<id>")
test_expect_success "Publish test text file to IPNS using RSA keys" '
PEERID=$(ipfs key gen -f=b58mh --type=rsa --size=2048 test_key_rsa | head -n1 | tr -d "\n")
IPNS_IDv0=$(echo "$PEERID" | ipfs cid format -v 0)
IPNS_IDv1=$(echo "$PEERID" | ipfs cid format -v 1 --codec libp2p-key -b base36)
IPNS_IDv1_DAGPB=$(echo "$IPNS_IDv0" | ipfs cid format -v 1 -b base36)
test_check_peerid "${PEERID}" &&
ipfs name publish --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
ipfs name publish --key test_key_rsa --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
ipfs name resolve "$PEERID" > output &&
printf "/ipfs/%s\n" "$CIDv1" > expected2 &&
test_cmp expected2 output
'
test_expect_success "Publish test text file to IPNS using ED25519 keys" '
PEERID=$(ipfs key gen -f=b36cid --type=ed25519 test_key_ed25519 | head -n1 | tr -d "\n") &&
IPNS_IDv0=$PEERID
IPNS_IDv1=$PEERID
IPNS_IDv1_DAGPB=$(echo "$IPNS_IDv0" | ipfs cid format -v 1 -b base32)
test_check_peerid "${PEERID}" &&
ipfs name publish --key test_key_ed25519 --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
ipfs name resolve "$PEERID" > output &&
printf "/ipfs/%s\n" "$CIDv1" > expected2 &&
test_cmp expected2 output
@ -272,7 +285,7 @@ test_localhost_gateway_response_should_contain \
"$CID_VAL"
test_localhost_gateway_response_should_contain \
"request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
"localhost request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
"http://${IPNS_IDv1_DAGPB}.ipns.localhost:$GWAY_PORT" \
"Location: http://${IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
@ -410,7 +423,7 @@ test_hostname_gateway_response_should_contain \
"$CID_VAL"
test_hostname_gateway_response_should_contain \
"request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
"hostname request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
"${IPNS_IDv1_DAGPB}.ipns.example.com" \
"http://127.0.0.1:$GWAY_PORT" \
"Location: http://${IPNS_IDv1}.ipns.example.com/"