6317843dfe319de90a3bed8bcbedc15c367fecdd
[nonrtric.git] / service-exposure / utils / pemtojwks / pemtojwks.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2022: Nordix Foundation
6 //   %%
7 //   Licensed under the Apache License, Version 2.0 (the "License");
8 //   you may not use this file except in compliance with the License.
9 //   You may obtain a copy of the License at
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
13 //   Unless required by applicable law or agreed to in writing, software
14 //   distributed under the License is distributed on an "AS IS" BASIS,
15 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 //   See the License for the specific language governing permissions and
17 //   limitations under the License.
18 //   ========================LICENSE_END===================================
19 //
20 package pemtojwks
21
22 import (
23         "crypto/rsa"
24         "crypto/sha1"
25         "crypto/x509"
26         "encoding/base64"
27         "encoding/json"
28         "encoding/pem"
29         "fmt"
30         "golang.org/x/crypto/ssh"
31         "io/ioutil"
32         "math/big"
33 )
34
35 type Jwks struct {
36         Keys []Key `json:"keys"`
37 }
38 type Key struct {
39         Kid string `json:"kid,omitempty"`
40         Kty string `json:"kty"`
41         Use string `json:"use"`
42         N   string `json:"n"`
43         E   string `json:"e"`
44         X5c []string `json:"x5c"`
45         X5t string `json:"x5t"`
46 }
47
48 func getKeyFromPrivate(key []byte) *rsa.PublicKey {
49         parsed, err := ssh.ParseRawPrivateKey(key)
50         if err != nil {
51                 fmt.Println(err)
52         }
53
54         // Convert back to an *rsa.PrivateKey
55         privateKey := parsed.(*rsa.PrivateKey)
56
57         publicKey := &privateKey.PublicKey
58         return publicKey
59 }
60
61 func getKeyFromPublic(key []byte) *rsa.PublicKey {
62         pubPem, _ := pem.Decode(key)
63
64         parsed, err := x509.ParsePKIXPublicKey(pubPem.Bytes)
65         if err != nil {
66                 fmt.Println("Unable to parse RSA public key", err)
67         }
68
69         // Convert back to an *rsa.PublicKey
70         publicKey := parsed.(*rsa.PublicKey)
71
72         return publicKey
73 }
74
75 func getCert(cert []byte) *x509.Certificate {
76         certPem, _ := pem.Decode(cert)
77         if certPem == nil {
78                 panic("Failed to parse pem file")
79         }
80
81         // pass cert bytes
82         certificate, err := x509.ParseCertificate(certPem.Bytes)
83         if err != nil {
84                 fmt.Println("Unable to parse Certificate", err)
85         }
86
87         return certificate
88 }
89
90 func getPublicKeyFromCert(cert_bytes []byte) *rsa.PublicKey {
91         block, _ := pem.Decode([]byte(cert_bytes))
92         var cert *x509.Certificate
93         cert, _ = x509.ParseCertificate(block.Bytes)
94         rsaPublicKey := cert.PublicKey.(*rsa.PublicKey)
95
96         return rsaPublicKey
97 }
98
99 func CreateJWKS(certFile string) string {
100         var publicKey *rsa.PublicKey
101
102         cert, err := ioutil.ReadFile(certFile)
103         if err != nil {
104                 fmt.Println(err)
105         }
106         publicKey = getPublicKeyFromCert(cert)
107
108         certificate := getCert(cert)
109         // generate fingerprint with sha1
110         // you can also use md5, sha256, etc.
111         fingerprint := sha1.Sum(certificate.Raw)
112
113
114         jwksKey := Key{
115                 Kid: "SIGNING_KEY",
116                 Kty: "RSA",
117                 Use: "sig",
118                 N: base64.RawStdEncoding.EncodeToString(publicKey.N.Bytes()),
119                 E: base64.RawStdEncoding.EncodeToString(big.NewInt(int64(publicKey.E)).Bytes()),
120                 X5c: []string{base64.RawStdEncoding.EncodeToString(certificate.Raw)},
121                 X5t: base64.RawStdEncoding.EncodeToString(fingerprint[:]),
122         }
123         jwksKeys := []Key{jwksKey}
124         jwks := Jwks{jwksKeys}
125
126         jwksJson, err := json.Marshal(jwks)
127         if err != nil {
128                 fmt.Println(err)
129                 return err.Error()
130         }
131         return string(jwksJson)
132
133 }