Update keycloak version
[nonrtric.git] / service-exposure / utils / pemtojwks / pemtojwks.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2022-2023: 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         Alg string `json:"alg"`
42         Use string `json:"use"`
43         N   string `json:"n"`
44         E   string `json:"e"`
45         X5c []string `json:"x5c"`
46         X5t string `json:"x5t"`
47 }
48
49 func getKeyFromPrivate(key []byte) *rsa.PublicKey {
50         parsed, err := ssh.ParseRawPrivateKey(key)
51         if err != nil {
52                 fmt.Println(err)
53         }
54
55         // Convert back to an *rsa.PrivateKey
56         privateKey := parsed.(*rsa.PrivateKey)
57
58         publicKey := &privateKey.PublicKey
59         return publicKey
60 }
61
62 func getKeyFromPublic(key []byte) *rsa.PublicKey {
63         pubPem, _ := pem.Decode(key)
64
65         parsed, err := x509.ParsePKIXPublicKey(pubPem.Bytes)
66         if err != nil {
67                 fmt.Println("Unable to parse RSA public key", err)
68         }
69
70         // Convert back to an *rsa.PublicKey
71         publicKey := parsed.(*rsa.PublicKey)
72
73         return publicKey
74 }
75
76 func getCert(cert []byte) *x509.Certificate {
77         certPem, _ := pem.Decode(cert)
78         if certPem == nil {
79                 panic("Failed to parse pem file")
80         }
81
82         // pass cert bytes
83         certificate, err := x509.ParseCertificate(certPem.Bytes)
84         if err != nil {
85                 fmt.Println("Unable to parse Certificate", err)
86         }
87
88         return certificate
89 }
90
91 func getPublicKeyFromCert(cert_bytes []byte) *rsa.PublicKey {
92         block, _ := pem.Decode([]byte(cert_bytes))
93         var cert *x509.Certificate
94         cert, _ = x509.ParseCertificate(block.Bytes)
95         rsaPublicKey := cert.PublicKey.(*rsa.PublicKey)
96
97         return rsaPublicKey 
98 }
99
100 func CreateJWKS(certFile string) (string, string, string) {
101         var publicKey *rsa.PublicKey
102         var kid string = "SIGNING_KEY"
103
104         cert, err := ioutil.ReadFile(certFile)
105         if err != nil {
106                 fmt.Println(err)
107         }
108         publicKey = getPublicKeyFromCert(cert)
109         publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
110         if err != nil {
111                 fmt.Println(err)
112         }
113         publicKeyPem := pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: publicKeyBytes})
114         block, _ := pem.Decode(publicKeyPem)
115         publicKeyString := base64.StdEncoding.EncodeToString(block.Bytes)
116
117         certificate := getCert(cert)
118         // generate fingerprint with sha1
119         // you can also use md5, sha256, etc.
120         fingerprint := sha1.Sum(certificate.Raw)
121
122         jwksKey := Key{
123                 Kid: kid,
124                 Kty: "RSA",
125                 Alg: "RS256",
126                 Use: "sig",
127                 N: base64.RawStdEncoding.EncodeToString(publicKey.N.Bytes()),
128                 E: base64.RawStdEncoding.EncodeToString(big.NewInt(int64(publicKey.E)).Bytes()),
129                 X5c: []string{base64.RawStdEncoding.EncodeToString(certificate.Raw)},
130                 X5t: base64.RawStdEncoding.EncodeToString(fingerprint[:]),
131         }
132         jwksKeys := []Key{jwksKey}
133         jwks := Jwks{jwksKeys}
134
135         jwksJson, err := json.Marshal(jwks)
136         if err != nil {
137                 fmt.Println(err)
138         }
139         return string(jwksJson), publicKeyString, kid
140
141 }