Skip to content

Commit

Permalink
Choosable key types at initialization
Browse files Browse the repository at this point in the history
* add support for choosing a peer key type (e.g. RSA or Ed25519) when initializing the repo
* test all variants of ipfs init: RSA, Ed25519 and default
* update subdomain gateway sharness test to publish IPNS using RSA and
Ed25519 keys
* use default identity bit lengths defined in config repo instead of
having separate defaults in go-ipfs
* update config repo dependency

Co-authored-by: Will Scott <will@cypherpunk.email>
Co-authored-by: Petar Maymounkov <petarm@gmail.com>
  • Loading branch information
2 people authored and aschmahmann committed Jul 14, 2020
1 parent b3e5ffc commit 4674f77
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 100 deletions.
10 changes: 9 additions & 1 deletion cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
}
Expand Down
42 changes: 33 additions & 9 deletions cmd/ipfs/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down Expand Up @@ -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 ','"),

Expand Down Expand Up @@ -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

Expand All @@ -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)
},
}

Expand All @@ -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
}
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
2 changes: 1 addition & 1 deletion test/sharness/lib/test-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
227 changes: 144 additions & 83 deletions test/sharness/t0020-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 "<aver>" | 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 "<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" '
Expand All @@ -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" '
Expand Down Expand Up @@ -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" '
Expand Down
Loading

0 comments on commit 4674f77

Please sign in to comment.