...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package main
23
24
27 import "C"
28
29 import (
30 "crypto"
31 "crypto/ecdsa"
32 "crypto/rsa"
33 "encoding/pem"
34 "io"
35 "log"
36 "os"
37 "unsafe"
38
39 "github.com/googleapis/enterprise-certificate-proxy/client"
40 )
41
42
43
44 func enableECPLogging() bool {
45 if os.Getenv("ENABLE_ENTERPRISE_CERTIFICATE_LOGS") != "" {
46 return true
47 }
48
49 log.SetOutput(io.Discard)
50 return false
51 }
52
53 func getCertPem(configFilePath string) []byte {
54 key, err := client.Cred(configFilePath)
55 if err != nil {
56 log.Printf("Could not create client using config %s: %v", configFilePath, err)
57 return nil
58 }
59 defer func() {
60 if err = key.Close(); err != nil {
61 log.Printf("Failed to clean up key. %v", err)
62 }
63 }()
64
65 certChain := key.CertificateChain()
66 certChainPem := []byte{}
67 for i := 0; i < len(certChain); i++ {
68 certPem := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certChain[i]})
69 certChainPem = append(certChainPem, certPem...)
70 }
71 return certChainPem
72 }
73
74
75
76
77
78
79
80
81
82 func GetCertPemForPython(configFilePath *C.char, certHolder *byte, certHolderLen int) int {
83 enableECPLogging()
84 pemBytes := getCertPem(C.GoString(configFilePath))
85 if certHolder != nil {
86 cert := unsafe.Slice(certHolder, certHolderLen)
87 copy(cert, pemBytes)
88 }
89 return len(pemBytes)
90 }
91
92
93
94
95
96 func SignForPython(configFilePath *C.char, digest *byte, digestLen int, sigHolder *byte, sigHolderLen int) int {
97
98 enableECPLogging()
99 key, err := client.Cred(C.GoString(configFilePath))
100 if err != nil {
101 log.Printf("Could not create client using config %s: %v", C.GoString(configFilePath), err)
102 return 0
103 }
104 defer func() {
105 if err = key.Close(); err != nil {
106 log.Printf("Failed to clean up key. %v", err)
107 }
108 }()
109 var isRsa bool
110 switch key.Public().(type) {
111 case *ecdsa.PublicKey:
112 isRsa = false
113 log.Print("the key is ecdsa key")
114 case *rsa.PublicKey:
115 isRsa = true
116 log.Print("the key is rsa key")
117 default:
118 log.Printf("unsupported key type")
119 return 0
120 }
121
122
123 digestSlice := unsafe.Slice(digest, digestLen)
124 var signature []byte
125 var signErr error
126 if isRsa {
127
128 opts := rsa.PSSOptions{
129 SaltLength: digestLen,
130 Hash: crypto.SHA256,
131 }
132
133 signature, signErr = key.Sign(nil, digestSlice, &opts)
134 } else {
135 signature, signErr = key.Sign(nil, digestSlice, crypto.SHA256)
136 }
137 if signErr != nil {
138 log.Printf("failed to sign hash: %v", signErr)
139 return 0
140 }
141 if sigHolderLen < len(signature) {
142 log.Printf("The sigHolder buffer size %d is smaller than the signature size %d", sigHolderLen, len(signature))
143 return 0
144 }
145
146
147 outBytes := unsafe.Slice(sigHolder, sigHolderLen)
148 copy(outBytes, signature)
149 return len(signature)
150 }
151
152
153
154
155
156 func GetKeyType(configFilePath *C.char) *C.char {
157 key, err := client.Cred(C.GoString(configFilePath))
158 if err != nil {
159 log.Printf("Could not create client using config %s: %v", C.GoString(configFilePath), err)
160 return C.CString("unknown")
161 }
162 defer func() {
163 if err = key.Close(); err != nil {
164 log.Printf("Failed to clean up key. %v", err)
165 }
166 }()
167 switch key.Public().(type) {
168 case *ecdsa.PublicKey:
169 return C.CString("EC")
170 case *rsa.PublicKey:
171 return C.CString("RSA")
172 default:
173 return C.CString("unknown")
174 }
175 }
176
177 func main() {}
178
View as plain text