diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 11769dbd031..a04fbed720c 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -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 } } diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 03851452087..4359c19a712 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -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 } diff --git a/go.mod b/go.mod index 7dac7eb6111..d1009a87969 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 11a11901ee1..8a418b298f1 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 4b7fd32aa61..f9716b13ad7 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -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 } diff --git a/test/sharness/t0020-init.sh b/test/sharness/t0020-init.sh index 3e0d9265818..e73b0562ec3 100755 --- a/test/sharness/t0020-init.sh +++ b/test/sharness/t0020-init.sh @@ -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 -' - -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 config succeeds" ' - echo /ipfs >expected_config && - ipfs config Mounts.IPFS >actual_config && - test_cmp expected_config actual_config -' - -test_expect_success "ipfs peer id looks good" ' - PEERID=$(ipfs config Identity.PeerID) && - test_check_peerid "$PEERID" -' - -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 "Welcome readme exists" ' - ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme -' - -test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" -' - -test_expect_success "'ipfs init --empty-repo' succeeds" ' - BITS="2048" && - ipfs init --bits="$BITS" --empty-repo >actual_init -' - -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 "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 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 "" | grep $(ipfs version -n) -' - -test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" -' +# $1 must be one of 'rsa', 'ed25519' or '' (for default key algorithm). +test_ipfs_init_flags() { + TEST_ALG=$1 + + # 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/ 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 config succeeds" ' + echo /ipfs >expected_config && + ipfs config Mounts.IPFS >actual_config && + test_cmp expected_config actual_config + ' + + test_expect_success "ipfs peer id looks good" ' + PEERID=$(ipfs config Identity.PeerID) && + test_check_peerid "$PEERID" + ' + + test_expect_success "ipfs init output looks good" ' + STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" && + + 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 && + + 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 && + + 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 exists" ' + ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme + ' + + test_expect_success "clean up ipfs dir" ' + rm -rf "$IPFS_PATH" + ' + + 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 "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 "" | 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" ' diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index f38a6db39ce..f21dcfbed87 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -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="") +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/"