1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
/*-
* Copyright 2019 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package main
import (
"bufio"
"encoding/base64"
"fmt"
"io"
"os"
kingpin "gopkg.in/alecthomas/kingpin.v2"
generator "github.com/go-jose/go-jose/jose-util/generator"
jose "github.com/go-jose/go-jose/v3"
)
var (
app = kingpin.New("jose-util", "A command-line utility for dealing with JOSE objects")
// Util-wide flags
keyFile = app.Flag("key", "Path to key file (if applicable, PEM, DER or JWK format)").ExistingFile()
inFile = app.Flag("in", "Path to input file (if applicable, stdin if missing)").ExistingFile()
outFile = app.Flag("out", "Path to output file (if applicable, stdout if missing)").ExistingFile()
// Encrypt
encryptCommand = app.Command("encrypt", "Encrypt a plaintext, output ciphertext")
encryptAlgFlag = encryptCommand.Flag("alg", "Key management algorithm (e.g. RSA-OAEP)").Required().String()
encryptEncFlag = encryptCommand.Flag("enc", "Content encryption algorithm (e.g. A128GCM)").Required().String()
encryptFullFlag = encryptCommand.Flag("full", "Use JSON Serialization format (instead of compact)").Bool()
// Decrypt
decryptCommand = app.Command("decrypt", "Decrypt a ciphertext, output plaintext")
// Sign
signCommand = app.Command("sign", "Sign a payload, output signed message")
signAlgFlag = signCommand.Flag("alg", "Key management algorithm (e.g. RSA-OAEP)").Required().String()
signFullFlag = signCommand.Flag("full", "Use JSON Serialization format (instead of compact)").Bool()
// Verify
verifyCommand = app.Command("verify", "Verify a signed message, output payload")
// Expand
expandCommand = app.Command("expand", "Expand JOSE object to JSON Serialization format")
expandFormatFlag = expandCommand.Flag("format", "Type of message to expand (JWS or JWE, defaults to JWE)").String()
// Base64-decode
base64DecodeCommand = app.Command("b64decode", "Decode a base64-encoded payload (auto-selects standard/url-safe)")
// Generate key
generateCommand = app.Command("generate-key", "Generate a public/private key pair in JWK format")
generateUseFlag = generateCommand.Flag("use", "Desired public key usage (use header), one of [enc sig]").Required().Enum("enc", "sig")
generateAlgFlag = generateCommand.Flag("alg", "Desired key pair algorithm (alg header)").Required().Enum(
// For signing
string(jose.EdDSA),
string(jose.ES256), string(jose.ES384), string(jose.ES512),
string(jose.RS256), string(jose.RS384), string(jose.RS512),
string(jose.PS256), string(jose.PS384), string(jose.PS512),
// For encryption
string(jose.RSA1_5), string(jose.RSA_OAEP), string(jose.RSA_OAEP_256),
string(jose.ECDH_ES), string(jose.ECDH_ES_A128KW), string(jose.ECDH_ES_A192KW), string(jose.ECDH_ES_A256KW),
)
generateKeySizeFlag = generateCommand.Flag("size", "Key size in bits (e.g. 2048 if generating an RSA key)").Int()
generateKeyIdentFlag = generateCommand.Flag("kid", "Optional Key ID (kid header, generate random kid if not set)").String()
)
func main() {
app.Version("v3")
app.UsageTemplate(kingpin.LongHelpTemplate)
command := kingpin.MustParse(app.Parse(os.Args[1:]))
switch command {
case encryptCommand.FullCommand():
encrypt()
case decryptCommand.FullCommand():
decrypt()
case signCommand.FullCommand():
sign()
case verifyCommand.FullCommand():
verify()
case expandCommand.FullCommand():
expand()
case generateCommand.FullCommand():
generate()
case base64DecodeCommand.FullCommand():
in := inputStream(*inFile)
out := outputStream(*outFile)
io.Copy(out, base64.NewDecoder(base64.RawStdEncoding, generator.Base64Reader{In: bufio.NewReader(in)}))
defer in.Close()
defer out.Close()
default:
fmt.Fprintf(os.Stderr, "invalid command: %s\n", command)
os.Exit(1)
}
}
|