Skip to content

Commit 2d84524

Browse files
committed
add golang tls sig api
1 parent 7364212 commit 2d84524

File tree

6 files changed

+556
-1
lines changed

6 files changed

+556
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
# tls-sig-api-golang
1+
# tls-sig-api-golang
2+
3+
only support P224/P256/P384/P521 curves

base64url.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package TLSSigAPI
2+
3+
import (
4+
"encoding/base64"
5+
"strings"
6+
)
7+
8+
func base64urlEncode(data []byte) string {
9+
str := base64.StdEncoding.EncodeToString(data)
10+
str = strings.Replace(str, "+", "*", -1)
11+
str = strings.Replace(str, "/", "-", -1)
12+
str = strings.Replace(str, "=", "_", -1)
13+
return str
14+
}
15+
16+
func base64urlDecode(str string) ([]byte, error) {
17+
str = strings.Replace(str, "_", "=", -1)
18+
str = strings.Replace(str, "-", "/", -1)
19+
str = strings.Replace(str, "*", "+", -1)
20+
return base64.StdEncoding.DecodeString(str)
21+
}

pem.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package TLSSigAPI
2+
3+
import (
4+
"crypto/ecdsa"
5+
"crypto/x509"
6+
"encoding/pem"
7+
"errors"
8+
)
9+
10+
var (
11+
ErrorInvalidKeyType = errors.New("invalid key type")
12+
)
13+
14+
func readPrivateKey(privateKey string) (*ecdsa.PrivateKey, error) {
15+
var restPem []byte
16+
restPem = []byte(privateKey)
17+
for len(restPem) > 0 {
18+
var block *pem.Block
19+
block, restPem = pem.Decode(restPem)
20+
if block == nil {
21+
break
22+
}
23+
switch block.Type {
24+
case "EC PRIVATE KEY": // pkcs1
25+
return x509.ParseECPrivateKey(block.Bytes)
26+
case "PRIVATE KEY": // pkcs8
27+
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
28+
if err == nil {
29+
switch key.(type) {
30+
case *ecdsa.PrivateKey:
31+
return key.(*ecdsa.PrivateKey), err
32+
default:
33+
return nil, ErrorInvalidKeyType
34+
}
35+
} else {
36+
return nil, err
37+
}
38+
case "EC PARAMETERS":
39+
break
40+
default:
41+
return nil, ErrorInvalidKeyType
42+
}
43+
}
44+
return nil, errors.New("invalid pem")
45+
}
46+
47+
func readPublicKey(publicKey string) (*ecdsa.PublicKey, error) {
48+
var restPem []byte
49+
restPem = []byte(publicKey)
50+
for len(restPem) > 0 {
51+
var block *pem.Block
52+
block, restPem = pem.Decode(restPem)
53+
if block == nil {
54+
break
55+
}
56+
switch block.Type {
57+
case "PUBLIC KEY": // pkcs1
58+
key, err := x509.ParsePKIXPublicKey(block.Bytes)
59+
if err == nil {
60+
switch key.(type) {
61+
case *ecdsa.PublicKey:
62+
return key.(*ecdsa.PublicKey), nil
63+
default:
64+
return nil, ErrorInvalidKeyType
65+
}
66+
} else {
67+
return nil, err
68+
}
69+
default:
70+
return nil, ErrorInvalidKeyType
71+
}
72+
}
73+
return nil, errors.New("invalid pem")
74+
}

pem_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package TLSSigAPI
2+
3+
import "testing"
4+
5+
func TestReadPKCS8PrivateKey(t *testing.T) {
6+
const text = `-----BEGIN PRIVATE KEY-----
7+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQge7zMZ+lq7I0nR4xP
8+
y2r0UwBGxiFwY+d3VD+mQs9QzF6hRANCAASdVKOtE5Aanc1XftuhKqvEijkmR38h
9+
nFZLl1pPiAlMLNqBJkbcWpM8fKSvgZdfNP6j9omW8pVeLuSy2FIc5Sap
10+
-----END PRIVATE KEY-----
11+
`
12+
key, err := readPrivateKey(text)
13+
if err != nil {
14+
t.Fatal(err)
15+
}
16+
if key == nil {
17+
t.Fatal("key is nil")
18+
}
19+
}
20+
21+
func TestReadECPrivateKey(t *testing.T) {
22+
const text = `-----BEGIN EC PARAMETERS-----
23+
BggqhkjOPQMBBw==
24+
-----END EC PARAMETERS-----
25+
-----BEGIN EC PRIVATE KEY-----
26+
MHcCAQEEIC3W2j45mRQ2BqDTET2AuiSK4sPJJump68HLzFQgCcL4oAoGCCqGSM49
27+
AwEHoUQDQgAE0YIf/QBsIeWN3MIoK2uLGICuYAus8MKaHkEEzTDHu+sfp7RHCGKW
28+
xiDFmeD8IQd3ue9bjZ+i1fFrV4dflvtg3A==
29+
-----END EC PRIVATE KEY-----
30+
`
31+
key, err := readPrivateKey(text)
32+
if err != nil {
33+
t.Fatal(err)
34+
}
35+
if key == nil {
36+
t.Fatal("key is nil")
37+
}
38+
}
39+
40+
func TestReadPublicKey(t *testing.T) {
41+
const text = `-----BEGIN PUBLIC KEY-----
42+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP1ddui+JqlZnztysAZLNqc+rdpip
43+
ExanYClZbXytFGEL/uJjfVC2pPoTBpKEU9V08BD+qZdD05J+KRxK794A7w==
44+
-----END PUBLIC KEY-----
45+
`
46+
key, err := readPublicKey(text)
47+
if err != nil {
48+
t.Fatal(err)
49+
}
50+
if key == nil {
51+
t.Fatal("key is nil")
52+
}
53+
}
54+
55+
func TestBadText(t *testing.T) {
56+
_, err := readPublicKey("asd")
57+
if err == nil {
58+
t.Fatal("should bee error")
59+
}
60+
61+
_, err = readPrivateKey("asd")
62+
if err == nil {
63+
t.Fatal("should bee error")
64+
}
65+
}
66+
67+
func TestOtherKey(t *testing.T) {
68+
_, err := readPrivateKey(`-----BEGIN RSA PRIVATE KEY-----
69+
MIIEpgIBAAKCAQEA3Zms7sWL668BhuN2C1UkcL2hiXpoZGD4nhielSLsrpKyccMj
70+
sUaNh96wTXxWBR+lW5DVbs/auaQYChLEGL8VD7kEwGKqp/9rJ9QPGVHqRyb1HFy/
71+
k5QjyKlpULFpy6LaiCrKJrruL82YK3W/hPm+l/PdT2ZsNJgnhg9xfMcGDKTWTewL
72+
SAmyt4M8byOXmigsofsnWCMQsULqjQ8yD6NhRKIs/Tqg4gczYsbrzqpATQvRCGkI
73+
IfW+RfTLnstaLq866amTa9GICvqYrI1PPi9qdtR4ju9bSZ+Iu3GAANd06y0AFNUF
74+
gwS+aAlejtuWysJVGmLFCFRiiqidnODus/RgkQIDAQABAoIBAQCv2sxJj6tCFVd4
75+
2/lJdP++GD6hAurk/a9OhusSHu0EfJXvgZRJkluufyIZ25nH5x0qVP2LOpewym/p
76+
TosfuEPWflUu9x3GxAMdUEPLLB5m6JuLLm85hk3/Z7GTv7bdSxdxB8P0iFOMy/L+
77+
Sir6M9b0byopYHZuJnD3CjpdcvNyA8MyY+jgAq6mzX4IfwqV/EKesiqxwXFB9Q0k
78+
iiBV1XGni+NuBRHt4BU/4Org+RS025dMMHE4FM9cm7qMmaeXJ6O9cQkCIaYWIybm
79+
rra1DS5e1+E2SdsyHK9Kc45730A2Db/eNoHuhc8BR5JG8Q4nRS7eZIh/1aTCVqyS
80+
udnvuBWBAoGBAPocoa2oLiAIkducN3MUW16opFncr5H8miseDRleSR/xmWIWdQ9g
81+
yYR75AA73KyiAV9PfgjwLIrbToWYejI/De//6TWSTFzavcqKTtTaE3zHF93rIg6S
82+
781J7VU6G2Z0U7mfs9ArwQl0WwUKhBV1xO2G9eGkYGksukxkx05+HcZVAoGBAOLR
83+
NhHXPu6BwVoZnxBL9WahTe+GfwSdjWJVuxKrBgbmwWJ1ys5UiVBkv9IB6Oq+iB7A
84+
t1hOOhoW1jON9JiD7vjm5IYUOHVMx+ekXM/7Q6UDYqnFLgukBYf62suZ5MD7A2GR
85+
4lHxv3JJ2S0Q3hN21siMM8t3Vh9J3s62Mq/gD9VNAoGBAOZgpRPeC8551lAgznpz
86+
z82bLPeQ7S9dK2x327z4OgbwdUYCRYUKs9QSgestOJDTEMyH3iHBiGXGp8cqsbPC
87+
nMXqRReRUEFfQt5jE0XAMZ8HjBZfVRlzgurnI3MTeNWgZNZgIjKnesGIqaY1D4Ds
88+
352iaK2UyTFXf6qKUYMda7OZAoGBANJyeO+OvjY/sC2wDhTp1VSXH5+5M8sNf+wY
89+
TU2h3yKyIgX/8t8EMq+j+xKYcQq1I8kc2ECXvHMOc0o8URDdgPHyEWCSDFxRlD1K
90+
FE9o+7d0b6vDZtioI/Wp/C3iqQuhGt8Bo3KSkiYxfM7CkrqOjfRfmYMUQ5UeThuP
91+
k3H5u9cVAoGBALABu3AurYqu7gN/HzdfdyxhacvMpDP02tm+OSuH87/i9f7oi6zr
92+
cZ2EtfrJeQV8uDXtWn+SkrceReaVHnt6GuWsECsV8HJ0/bkw4G0+ibvM6sb/e0lm
93+
fzFFWwTuYuMEElUhHecd1OJAbE/5KJWY1vBAjGrIYKsBDF46lO4a1PRD
94+
-----END RSA PRIVATE KEY-----`)
95+
if err != ErrorInvalidKeyType {
96+
t.Fatal(err)
97+
}
98+
_, err = readPublicKey(`-----BEGIN PUBLIC KEY-----
99+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UoakJ205m2VIvxSWIwA
100+
vy3doqotRvdsz5Z67bfm0d2tDae3jHpJUaoQ2wR3jDGUdf1srcq66Z53amMT9LEw
101+
WpVdZcTcMERA8DguwAoUwaOJiivG/IcUXK2r9HaA7/dt6V/OUT8sOWOcEbOB18vs
102+
EE3lxVccz7SOs//IeFUCCwnbx5YwAHbXz0b4VUBH8PtWGvE5nhuiexmTMAdPiLkn
103+
vSEzdQQshSqd3n1H0gHb+YwQcAbU6x7Fv4OggmkmidETeBJQvUzuSR4FLRHqgugx
104+
WHu3ctVnDXITNH/ZyDBpekgkHTiLC3SGJB3iao5Az+0ndEYz+LEZqgDHuNrmY9gn
105+
gQIDAQAB
106+
-----END PUBLIC KEY-----`)
107+
if err != ErrorInvalidKeyType {
108+
t.Fatal(err)
109+
}
110+
111+
}

0 commit comments

Comments
 (0)