-
Notifications
You must be signed in to change notification settings - Fork 174
/
main.go
96 lines (80 loc) · 2.07 KB
/
main.go
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
package main
import (
"crypto"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/pkg/errors"
jose "gopkg.in/square/go-jose.v2"
)
// copied from kubernetes/kubernetes#78502
func keyIDFromPublicKey(publicKey interface{}) (string, error) {
publicKeyDERBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return "", fmt.Errorf("failed to serialize public key to DER format: %v", err)
}
hasher := crypto.SHA256.New()
hasher.Write(publicKeyDERBytes)
publicKeyDERHash := hasher.Sum(nil)
keyID := base64.RawURLEncoding.EncodeToString(publicKeyDERHash)
return keyID, nil
}
type KeyResponse struct {
Keys []jose.JSONWebKey `json:"keys"`
}
func readKey(filename string) ([]byte, error) {
var response []byte
content, err := ioutil.ReadFile(filename)
if err != nil {
return response, errors.WithMessage(err, "error reading file")
}
block, _ := pem.Decode(content)
if block == nil {
return response, errors.Errorf("Error decoding PEM file %s", filename)
}
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return response, errors.Wrapf(err, "Error parsing key content of %s", filename)
}
switch pubKey.(type) {
case *rsa.PublicKey:
default:
return response, errors.New("Public key was not RSA")
}
var alg jose.SignatureAlgorithm
switch pubKey.(type) {
case *rsa.PublicKey:
alg = jose.RS256
default:
return response, fmt.Errorf("invalid public key type %T, must be *rsa.PrivateKey", pubKey)
}
kid, err := keyIDFromPublicKey(pubKey)
if err != nil {
return response, err
}
var keys []jose.JSONWebKey
keys = append(keys, jose.JSONWebKey{
Key: pubKey,
KeyID: kid,
Algorithm: string(alg),
Use: "sig",
})
keyResponse := KeyResponse{Keys: keys}
return json.MarshalIndent(keyResponse, "", " ")
}
func main() {
keyFile := flag.String("key", "", "The public key input file in PKCS8 format")
flag.Parse()
output, err := readKey(*keyFile)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
fmt.Println(string(output))
}