Skip to content

Commit

Permalink
docs: move kubo-specific docs (#10226)
Browse files Browse the repository at this point in the history
* docs: move kubo-specific docs
* chore: note crypt cmd does not exist

Context: ipfs/specs#455

---------

Co-authored-by: Marcin Rataj <lidel@lidel.org>
  • Loading branch information
hacdias and lidel committed Nov 20, 2023
1 parent 01cc5ea commit 48865a9
Show file tree
Hide file tree
Showing 5 changed files with 705 additions and 0 deletions.
Binary file added docs/specifications/fs-datastore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/specifications/ipfs-repo-contents.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
295 changes: 295 additions & 0 deletions docs/specifications/keystore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) Keystore

**Authors(s):**
- [whyrusleeping](github.com/whyrusleeping)
- [Hector Sanjuan](github.com/hsanjuan)

**Abstract**

This spec provides definitions and operations for the keystore feature in IPFS.

# Table of Contents

- [Goals](#goals)
- [Planned Implementation](#planned-implementation)
- [Key storage](#key-storage)
- [Interface](#interface)
- [Code changes and additions](#code-changes-and-additions)
- [Structures](#structures)

## Goals

To have a secure, simple and user-friendly way of storing and managing keys
for use by ipfs. As well as the ability to share these keys, encrypt, decrypt,
sign and verify data.

## Planned Implementation

### Key storage

Storage layout and format is defined in the [`repository_fs`](repository_fs.md) part of the spec.

### Interface

#### ipfs key

```
USAGE
ipfs key - Create and list IPNS name keypairs
ipfs key
'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name
publish'.
> ipfs key gen --type=rsa --size=2048 mykey
> ipfs name publish --key=mykey QmSomeHash
'ipfs key list' lists the available keys.
> ipfs key list
self
mykey
SUBCOMMANDS
ipfs key export <name> - Export a keypair
ipfs key gen <name> - Create a new keypair
ipfs key import <name> <key> - Import a key and prints imported key id
ipfs key list - List all local keypairs.
ipfs key rename <name> <newName> - Rename a keypair.
ipfs key rm <name>... - Remove a keypair.
ipfs key rotate - Rotates the IPFS identity.
For more information about each command, use:
'ipfs key <subcmd> --help'
```

#### ipfs crypt

**NOTE:** as of 2023 Q4, `ipfs crypt` commands are not implemented yet.

```
ipfs crypt - Perform cryptographic operations using ipfs keypairs
SUBCOMMANDS:
ipfs crypt sign <data> - Generates a signature for the given data with a specified key
ipfs crypt verify <data> <sig> - Verify that the given data and signature match
ipfs crypt encrypt <data> - Encrypt the given data
ipfs crypt decrypt <data> - Decrypt the given data
DESCRIPTION:
`ipfs crypt` is a command used to perform various cryptographic operations
using ipfs keypairs, including: signing, verifying, encrypting and decrypting.
```

#### Some subcommands:

##### ipfs key Gen


```
USAGE
ipfs key gen <name> - Create a new keypair
SYNOPSIS
ipfs key gen [--type=<type> | -t] [--size=<size> | -s]
[--ipns-base=<ipns-base>] [--] <name>
ARGUMENTS
<name> - name of key to create
OPTIONS
-t, --type string - type of the key to create: rsa, ed25519. Default:
ed25519.
-s, --size int - size of the key to generate.
--ipns-base string - Encoding used for keys: Can either be a multibase
encoded CID or a base58btc encoded multihash. Takes
{b58mh|base36|k|base32|b...}. Default: base36.
```

* * *

##### Key Send

```
USAGE
ipfs key - Create and list IPNS name keypairs
SYNOPSIS
ipfs key
DESCRIPTION
'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name
publish'.
> ipfs key gen --type=rsa --size=2048 mykey
> ipfs name publish --key=mykey QmSomeHash
'ipfs key list' lists the available keys.
> ipfs key list
self
mykey
SUBCOMMANDS
ipfs key export <name> - Export a keypair
ipfs key gen <name> - Create a new keypair
ipfs key import <name> <key> - Import a key and prints imported key id
ipfs key list - List all local keypairs.
ipfs key rename <name> <newName> - Rename a keypair.
ipfs key rm <name>... - Remove a keypair.
ipfs key rotate - Rotates the IPFS identity.
For more information about each command, use:
'ipfs key <subcmd> --help'
```

##### Comments:

Ensure that the user knows the implications of sending a key.

* * *

##### Crypt Encrypt

```
ipfs crypt encrypt <data> - Encrypt the given data with a specified key
ARGUMENTS:
data - The filename of the data to be encrypted ("-" for stdin)
OPTIONS:
-k, -key string - The name of the key to use for encryption (default: localkey)
-o, -output string - The name of the output file (default: stdout)
-c, -cipher string - The cipher to use for the operation
-m, -mode string - The block cipher mode to use for the operation
DESCRIPTION:
'ipfs crypt encrypt' is a command used to encypt data so that only holders of a certain
key can read it.
```

##### Comments:

This should probably just operate on raw data and not on DAGs.

* * *

##### Other Interface Changes

We will also need to make additions to support keys in other commands, these changes are as follows:

- `ipfs add`
- Support for a `-encrypt-key` option, for block encrypting the file being added with the key
- also adds an 'encrypted' node above the root unixfs node
- Support for a `-sign-key` option to attach a signature node above the root unixfs node

- `ipfs block put`
- Support for a `-encrypt-key` option, for encrypting the block before hashing and storing

- `ipfs object put`
- Support for a `-encrypt-key` option, for encrypting the object before hashing and storing

- `ipfs name publish`
- Support for a `-key` option to select which keyspace to publish to

### Code changes and additions

This sections outlines code organization around this feature.

#### Keystore package

The fsrepo carries a `keystore` that can be used to load/store keys. The keystore is implemented following this interface:

```go
// Keystore provides a key management interface
type Keystore interface {
// Has returns whether or not a key exist in the Keystore
Has(string) (bool, error)
// Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists
Put(string, ci.PrivKey) error
// Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey
// otherwise.
Get(string) (ci.PrivKey, error)
// Delete removes a key from the Keystore
Delete(string) error
// List returns a list of key identifier
List() ([]string, error)
}
```

Note: Never store passwords as strings, strings cannot be zeroed out after they are used.
using a byte array allows you to write zeroes over the memory so that the users password
does not linger in memory.

#### Unixfs

- new node types, 'encrypted' and 'signed', probably shouldn't be in unixfs, just understood by it
- if new node types are not unixfs nodes, special consideration must be given to the interop

- DagReader needs to be able to access keystore to seamlessly stream encrypted data we have keys for
- also needs to be able to verify signatures

#### Importer

- DagBuilderHelper needs to be able to encrypt blocks
- Dag Nodes should be generated like normal, then encrypted, and their parents should
link to the hash of the encrypted node
- DagBuilderParams should have extra parameters to accommodate creating a DBH that encrypts the blocks

#### New 'Encrypt' package

Should contain code for crypto operations on dags.

Encryption of dags should work by first generating a symmetric key, and using
that key to encrypt all the data. That key should then be encrypted with the
public key chosen and stored in the Encrypted DAG structure.

Note: One option is to simply add it to the key interface.

### Structures
Some tentative mockups (in json) of the new DAG structures for signing and encrypting

Signed DAG:
```
{
"Links" : [
{
"Name":"@content",
"Hash":"QmTheContent",
}
],
"Data": protobuf{
"Type":"Signed DAG",
"Signature": "thesignature",
"PubKeyID": "QmPubKeyHash",
}
}
```

Encrypted DAG:
```
{
"Links" : [
{
"Name":"@content",
"Hash":"QmRawEncryptedDag",
}
],
"Data": protobuf{
"Type":"Encrypted DAG",
"PubKeyID": "QmPubKeyHash",
"Key": "ephemeral symmetric key, encrypted with public key",
}
}
```
Loading

0 comments on commit 48865a9

Please sign in to comment.