Skip to content

Commit 6fd1344

Browse files
talentlessguySean-Der
authored andcommitted
Enable certificate.go for WASM builds
Go WASM interop supports x509, PEM and other cryptography functions (but not all), so there is no reason not to include those in the wasm build. This will also fix compilation errors for when something is using webrtc and targets both wasm and server The PR was tested locally (via a simple web folder with wasm_exec.js and index.html) and I confirmed being able to generate a X509 certificate
1 parent d08789b commit 6fd1344

File tree

3 files changed

+176
-3
lines changed

3 files changed

+176
-3
lines changed

certificate.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
22
// SPDX-License-Identifier: MIT
33

4-
//go:build !js
5-
// +build !js
6-
74
package webrtc
85

96
import (

certificate_js_test.go

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
//go:build js && wasm
2+
// +build js,wasm
3+
4+
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
5+
// SPDX-License-Identifier: MIT
6+
7+
package webrtc
8+
9+
import (
10+
"crypto/ecdsa"
11+
"crypto/elliptic"
12+
"crypto/rand"
13+
"crypto/rsa"
14+
"crypto/tls"
15+
"crypto/x509"
16+
"encoding/pem"
17+
"testing"
18+
"time"
19+
20+
"github.com/stretchr/testify/assert"
21+
)
22+
23+
func TestGenerateCertificateRSA(t *testing.T) {
24+
sk, err := rsa.GenerateKey(rand.Reader, 2048)
25+
assert.Nil(t, err)
26+
27+
skPEM := pem.EncodeToMemory(&pem.Block{
28+
Type: "RSA PRIVATE KEY",
29+
Bytes: x509.MarshalPKCS1PrivateKey(sk),
30+
})
31+
32+
cert, err := GenerateCertificate(sk)
33+
assert.Nil(t, err)
34+
35+
certPEM := pem.EncodeToMemory(&pem.Block{
36+
Type: "CERTIFICATE",
37+
Bytes: cert.x509Cert.Raw,
38+
})
39+
40+
_, err = tls.X509KeyPair(certPEM, skPEM)
41+
assert.Nil(t, err)
42+
}
43+
44+
func TestGenerateCertificateECDSA(t *testing.T) {
45+
sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
46+
assert.Nil(t, err)
47+
48+
skDER, err := x509.MarshalECPrivateKey(sk)
49+
assert.Nil(t, err)
50+
51+
skPEM := pem.EncodeToMemory(&pem.Block{
52+
Type: "EC PRIVATE KEY",
53+
Bytes: skDER,
54+
})
55+
56+
cert, err := GenerateCertificate(sk)
57+
assert.Nil(t, err)
58+
59+
certPEM := pem.EncodeToMemory(&pem.Block{
60+
Type: "CERTIFICATE",
61+
Bytes: cert.x509Cert.Raw,
62+
})
63+
64+
_, err = tls.X509KeyPair(certPEM, skPEM)
65+
assert.Nil(t, err)
66+
}
67+
68+
func TestGenerateCertificateEqual(t *testing.T) {
69+
sk1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
70+
assert.Nil(t, err)
71+
72+
sk3, err := rsa.GenerateKey(rand.Reader, 2048)
73+
assert.NoError(t, err)
74+
75+
cert1, err := GenerateCertificate(sk1)
76+
assert.Nil(t, err)
77+
78+
sk2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
79+
assert.Nil(t, err)
80+
81+
cert2, err := GenerateCertificate(sk2)
82+
assert.Nil(t, err)
83+
84+
cert3, err := GenerateCertificate(sk3)
85+
assert.NoError(t, err)
86+
87+
assert.True(t, cert1.Equals(*cert1))
88+
assert.False(t, cert1.Equals(*cert2))
89+
assert.True(t, cert3.Equals(*cert3))
90+
}
91+
92+
func TestGenerateCertificateExpires(t *testing.T) {
93+
sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
94+
assert.Nil(t, err)
95+
96+
cert, err := GenerateCertificate(sk)
97+
assert.Nil(t, err)
98+
99+
now := time.Now()
100+
assert.False(t, cert.Expires().IsZero() || now.After(cert.Expires()))
101+
102+
x509Cert := CertificateFromX509(sk, &x509.Certificate{})
103+
assert.NotNil(t, x509Cert)
104+
assert.Contains(t, x509Cert.statsID, "certificate")
105+
}
106+
107+
func TestPEM(t *testing.T) {
108+
sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
109+
assert.Nil(t, err)
110+
cert, err := GenerateCertificate(sk)
111+
assert.Nil(t, err)
112+
113+
pem, err := cert.PEM()
114+
assert.Nil(t, err)
115+
cert2, err := CertificateFromPEM(pem)
116+
assert.Nil(t, err)
117+
pem2, err := cert2.PEM()
118+
assert.Nil(t, err)
119+
assert.Equal(t, pem, pem2)
120+
}
121+
122+
const (
123+
certHeader = `!! This is a test certificate: Don't use it in production !!
124+
You can create your own using openssl
125+
` + "```sh" + `
126+
openssl req -new -sha256 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 ` +
127+
`-x509 -nodes -days 365 -out cert.pem -keyout cert.pem -subj "/CN=WebRTC"
128+
openssl x509 -in cert.pem -noout -fingerprint -sha256
129+
` + "```\n"
130+
131+
certPriv = `-----BEGIN PRIVATE KEY-----
132+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg2XFaTNqFpTUqNtG9
133+
A21MEe04JtsWVpUTDD8nI0KvchKhRANCAAS1nqME3jS5GFicwYfGDYaz7oSINwWm
134+
X4BkfsSCxMrhr7mPtfxOi4Lxy/P3w6EvSSEU8t5E9ouKIWh5xPS9dYwu
135+
-----END PRIVATE KEY-----
136+
`
137+
138+
certCert = `-----BEGIN CERTIFICATE-----
139+
MIIBljCCATugAwIBAgIUQa1sD+5HG43K+hCEVZLYxB68/hQwCgYIKoZIzj0EAwIw
140+
IDEeMBwGA1UEAwwVc3dpdGNoLmV2YW4tYnJhc3MubmV0MB4XDTI0MDQyNDIwMjEy
141+
MFoXDTI1MDQyNDIwMjEyMFowIDEeMBwGA1UEAwwVc3dpdGNoLmV2YW4tYnJhc3Mu
142+
bmV0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtZ6jBN40uRhYnMGHxg2Gs+6E
143+
iDcFpl+AZH7EgsTK4a+5j7X8TouC8cvz98OhL0khFPLeRPaLiiFoecT0vXWMLqNT
144+
MFEwHQYDVR0OBBYEFGecfGnYqZFVgUApHGgX2kSIhUusMB8GA1UdIwQYMBaAFGec
145+
fGnYqZFVgUApHGgX2kSIhUusMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID
146+
SQAwRgIhAJ3VWO8JZ7FEOJhxpUCeyOgl+G4vXSHtj9J9NRD3uGGZAiEAsTKGLOGE
147+
9c6CtLDU9Ohf1c+Xj2Yi9H+srLZj1mrsnd4=
148+
-----END CERTIFICATE-----
149+
`
150+
)
151+
152+
func TestOpensslCert(t *testing.T) {
153+
// Check that CertificateFromPEM can parse certificates with the PRIVATE KEY before the CERTIFICATE block
154+
_, err := CertificateFromPEM(certHeader + certPriv + certCert)
155+
assert.Nil(t, err)
156+
}
157+
158+
func TestEmpty(t *testing.T) {
159+
cert, err := CertificateFromPEM("")
160+
assert.Nil(t, cert)
161+
assert.Equal(t, errCertificatePEMMissing, err)
162+
}
163+
164+
func TestMultiCert(t *testing.T) {
165+
cert, err := CertificateFromPEM(certHeader + certCert + certPriv + certCert)
166+
assert.Nil(t, cert)
167+
assert.Equal(t, errCertificatePEMMultipleCert, err)
168+
}
169+
170+
func TestMultiPriv(t *testing.T) {
171+
cert, err := CertificateFromPEM(certPriv + certHeader + certCert + certPriv)
172+
assert.Nil(t, cert)
173+
assert.Equal(t, errCertificatePEMMultiplePriv, err)
174+
}

configuration_js.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ type Configuration struct {
3636

3737
// ICECandidatePoolSize describes the size of the prefetched ICE pool.
3838
ICECandidatePoolSize uint8
39+
40+
Certificates []Certificate `json:"certificates,omitempty"`
3941
}

0 commit comments

Comments
 (0)