mirror of
https://github.com/FiloSottile/age.git
synced 2026-09-02 14:17:10 +00:00
110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
// Copyright 2019 Google LLC
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"runtime/debug"
|
|
"time"
|
|
|
|
"filippo.io/age"
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
)
|
|
|
|
const usage = `Usage:
|
|
age-keygen [-o OUTPUT]
|
|
|
|
Options:
|
|
-o, --output OUTPUT Write the key to the file at path OUTPUT.
|
|
|
|
age-keygen generates a new standard X25519 key pair, and outputs it to
|
|
standard output or to the OUTPUT file.
|
|
|
|
If an OUTPUT file is specified, the public key is printed to standard error.
|
|
If OUTPUT already exists, it is not overwritten.
|
|
|
|
Examples:
|
|
|
|
$ age-keygen
|
|
# created: 2021-01-02T15:30:45+01:00
|
|
# public key: age1lvyvwawkr0mcnnnncaghunadrqkmuf9e6507x9y920xxpp866cnql7dp2z
|
|
AGE-SECRET-KEY-1N9JEPW6DWJ0ZQUDX63F5A03GX8QUW7PXDE39N8UYF82VZ9PC8UFS3M7XA9
|
|
|
|
$ age-keygen -o key.txt
|
|
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p`
|
|
|
|
// Version can be set at link time to override debug.BuildInfo.Main.Version,
|
|
// which is "(devel)" when building from within the module. See
|
|
// golang.org/issue/29814 and golang.org/issue/29228.
|
|
var Version string
|
|
|
|
func main() {
|
|
log.SetFlags(0)
|
|
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
|
|
|
|
var (
|
|
versionFlag bool
|
|
outFlag string
|
|
)
|
|
|
|
flag.BoolVar(&versionFlag, "version", false, "print the version")
|
|
flag.StringVar(&outFlag, "o", "", "output to `FILE` (default stdout)")
|
|
flag.StringVar(&outFlag, "output", "", "output to `FILE` (default stdout)")
|
|
flag.Parse()
|
|
if len(flag.Args()) != 0 {
|
|
log.Fatalf("age-keygen takes no arguments")
|
|
}
|
|
if versionFlag {
|
|
if Version != "" {
|
|
fmt.Println(Version)
|
|
return
|
|
}
|
|
if buildInfo, ok := debug.ReadBuildInfo(); ok {
|
|
fmt.Println(buildInfo.Main.Version)
|
|
return
|
|
}
|
|
fmt.Println("(unknown)")
|
|
return
|
|
}
|
|
|
|
out := os.Stdout
|
|
if outFlag != "" {
|
|
f, err := os.OpenFile(outFlag, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
|
if err != nil {
|
|
log.Fatalf("Failed to open output file %q: %v", outFlag, err)
|
|
}
|
|
defer f.Close()
|
|
out = f
|
|
}
|
|
|
|
if fi, err := out.Stat(); err == nil {
|
|
if fi.Mode().IsRegular() && fi.Mode().Perm()&0004 != 0 {
|
|
fmt.Fprintf(os.Stderr, "Warning: writing secret key to a world-readable file.\n")
|
|
}
|
|
}
|
|
|
|
generate(out)
|
|
}
|
|
|
|
func generate(out *os.File) {
|
|
k, err := age.GenerateX25519Identity()
|
|
if err != nil {
|
|
log.Fatalf("Internal error: %v", err)
|
|
}
|
|
|
|
if !terminal.IsTerminal(int(out.Fd())) {
|
|
fmt.Fprintf(os.Stderr, "Public key: %s\n", k.Recipient())
|
|
}
|
|
|
|
fmt.Fprintf(out, "# created: %s\n", time.Now().Format(time.RFC3339))
|
|
fmt.Fprintf(out, "# public key: %s\n", k.Recipient())
|
|
fmt.Fprintf(out, "%s\n", k)
|
|
}
|