Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions docs/security-util.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ ndnd sec sign-cert alice.key < alice.key > alice.cert
# Generate a key for /ndn/bob and create a certificate signed by /ndn/alice
# Sets the issuer field to ALICE
ndnd sec keygen /ndn/bob rsa 2048 > bob.key
ndnd sec sign-cert -issuer ALICE alice.key < bob.key > bob1.cert
ndnd sec sign-cert --issuer ALICE alice.key < bob.key > bob1.cert

# Create a certificate with a defined validity period
ndnd sec sign-cert -issuer ALICE -start 20150101000000 -end 20350101000000 alice.key < bob.key > bob2.cert
ndnd sec sign-cert --issuer ALICE --start 20150101000000 --end 20350101000000 alice.key < bob.key > bob2.cert

# Re-sign the public key in a certificate (or CSR) with a provided key
ndnd sec keygen /ndn/carol ed25519 > carol.key
ndnd sec sign-cert -issuer CAROL carol.key < bob1.cert > bob3.cert
ndnd sec sign-cert --issuer CAROL carol.key < bob1.cert > bob3.cert
```

## `ndnd sec key-list`

List all keys in the keychain.
List all keys and certs in the keychain.

```bash
# List all keys in the keychain directory /etc/app/keys
Expand Down Expand Up @@ -83,6 +83,15 @@ Delete a key (and its certificates) from the keychain.
ndnd sec key-delete dir:///etc/app/keys /ndn/bob/KEY/%A6%0Ei%1F%A8J%D4%8E
```

## `ndnd sec cert-export`

Export a certificate from the keychain.

```bash
# Export a specific certificate from a keychain
ndnd sec cert-export dir:///etc/app/keys /ndn/bob/KEY/%A6%0Ei%1F%A8J%D4%8E/self/v=1
```

## `ndnd sec cert-delete`

Delete a certificate from the keychain.
Expand Down
65 changes: 61 additions & 4 deletions tools/sec/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (t *ToolKeychain) configure(cmd *cobra.Command) {
cmd.AddCommand(&cobra.Command{
GroupID: "keychain",
Use: "key-list KEYCHAIN-URI",
Short: "List keys in a keychain",
Short: "List keys and certs in a keychain",
Run: t.List,
Args: cobra.ExactArgs(1),
Example: ` ndnd sec key-list dir:///safe/keys`,
Expand Down Expand Up @@ -74,9 +74,18 @@ and the default key of the identity will be exported.`,
Example: ` ndnd sec key-export dir:///safe/keys /alice`,
Run: t.Export,
})

cmd.AddCommand(&cobra.Command{
GroupID: "keychain",
Use: "cert-export KEYCHAIN-URI CERT-NAME",
Short: "Export a certificate from a keychain",
Args: cobra.ExactArgs(2),
Example: ` ndnd sec cert-export dir:///safe/keys /alice/KEY/~%E8t%A5%A3V%88%81/NA/v=0`,
Run: t.ExportCert,
})
}

// (AI GENERATED DESCRIPTION): Lists all identities and their keys in the keychain at the given path, printing each identity name followed by the names of its keys.
// Lists all identities, their keys, and the associated certs in the keychain at the given URI, printing each identity name followed by the names of its keys, then its names of its certs
func (*ToolKeychain) List(_ *cobra.Command, args []string) {
kc, err := keychain.NewKeyChain(args[0], storage.NewMemoryStore())
if err != nil {
Expand All @@ -89,11 +98,14 @@ func (*ToolKeychain) List(_ *cobra.Command, args []string) {
fmt.Printf("%s\n", id.Name())
for _, key := range id.Keys() {
fmt.Printf("==> %s\n", key.KeyName())
for _, cert := range key.UniqueCerts() {
fmt.Printf(" ==> %s\n", cert)
}
}
}
}

// (AI GENERATED DESCRIPTION): Imports keychain entries from standard input into the keychain named by the first argument, storing them in a memory-based keychain.
// Imports keychain entries from standard input into the keychain named by the first argument
func (*ToolKeychain) Import(_ *cobra.Command, args []string) {
kc, err := keychain.NewKeyChain(args[0], storage.NewMemoryStore())
if err != nil {
Expand All @@ -117,7 +129,7 @@ func (*ToolKeychain) Import(_ *cobra.Command, args []string) {
}
}

// (AI GENERATED DESCRIPTION): Exports a specified key (or an identity’s default key) from a keychain, PEM‑encodes its secret key, and writes it to standard output.
// Exports a specified key (or an identity’s default key) from a keychain, PEM‑encodes its secret key, and writes it to standard output.
func (*ToolKeychain) Export(_ *cobra.Command, args []string) {
name, err := enc.NameFromStr(args[1])
if err != nil {
Expand Down Expand Up @@ -205,6 +217,51 @@ func (*ToolKeychain) DeleteKey(_ *cobra.Command, args []string) {
}
}

// Exports a specified certificate from a keychain, PEM‑encodes it, and writes it to standard output.
func (*ToolKeychain) ExportCert(_ *cobra.Command, args []string) {
name, err := enc.NameFromStr(args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid certificate name: %s\n", args[1])
os.Exit(1)
return
}

kc, err := keychain.NewKeyChain(args[0], storage.NewMemoryStore())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to open keychain: %s\n", err)
os.Exit(1)
return
}

if name.At(-1).Typ == enc.TypeImplicitSha256DigestComponent {
name = name.Prefix(-1)
}

if name.At(-1).String() == "v=0" {
name = name.Prefix(-1)
}

wire, err := kc.Store().Get(name, false)
if err == nil && wire == nil {
wire, err = kc.Store().Get(name, true)
}

if err != nil || wire == nil {
fmt.Fprintf(os.Stderr, "Certificate not found: %s\n", name)
os.Exit(1)
return
}

out, err := security.PemEncode(enc.Wire{wire}.Join())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert certificate to text: %s\n", err)
os.Exit(1)
return
}

os.Stdout.Write(out)
}

// DeleteCert removes a certificate from the keychain.
func (*ToolKeychain) DeleteCert(_ *cobra.Command, args []string) {
name, err := enc.NameFromStr(args[1])
Expand Down
Loading