-
Notifications
You must be signed in to change notification settings - Fork 1
/
dial.go
128 lines (107 loc) · 3.38 KB
/
dial.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package client
import (
"crypto/tls"
"crypto/x509"
"fmt"
piondtls "github.com/pion/dtls/v2"
log "github.com/sirupsen/logrus"
"github.com/zourva/lwm2m/coap"
. "github.com/zourva/lwm2m/core"
"github.com/zourva/pareto/cipher"
)
type ServerInfo struct {
address string
// securityMode
// Determines which security mode is used
// - 0: PreShared Key mode
// - 1: Raw Public Key mode
// - 2: Certificate mode
// - 3: NoSec mode
// - 4: Certificate mode with EST
securityMode int
// publicKeyOrIdentity
// Stores the LwM2M Client's certificate, public key (RPK mode) or PSK Identity (PSK mode).
// securityMode is 2 : client certificate file
publicKeyOrIdentity []byte
// serverPublicKey
// Stores the LwM2M Server's, respectively LwM2M
// Bootstrap-Server's, certificate, public key (RPK mode) or trust anchor. The Certificate Mode
// Resource determines the content of this resource.
serverPublicKey []byte
// secretKey
// Stores the secret key (PSK mode) or private key(RPK or certificate mode).
// securityMode is 2 : client private key
secretKey []byte
}
func checkCommonName(name string, cert *tls.Certificate) error {
var commonName string
if cert.Leaf == nil {
if leaf, err := x509.ParseCertificate(cert.Certificate[0]); err != nil {
log.Errorf("x509 parser certificate failed, err:%v", err)
return err
} else {
commonName = leaf.Subject.CommonName
}
} else {
commonName = cert.Leaf.Subject.CommonName
}
if commonName != name {
err := fmt.Errorf("the Common Name(%s) in the client certificate does not match the device name(%s)",
commonName, name)
log.Errorf("%v", err)
return err
}
return nil
}
func loadDTLSConfig(client *LwM2MClient, server *ServerInfo) (*piondtls.Config, error) {
var dtlsConf *piondtls.Config
switch server.securityMode {
case SecurityModeCertificate:
cert, err := cipher.LoadKeyAndCertificate(server.secretKey, server.publicKeyOrIdentity)
if err != nil {
log.Errorf("load client key and certificate failed, err:%v", err)
return nil, err
}
if err = checkCommonName(client.name, cert); err != nil {
return nil, err
}
log.Debugf("load client key and certificate certificate file successfully")
var rootCertPool *x509.CertPool
if len(server.serverPublicKey) != 0 {
rootCertPool, err = cipher.LoadAllCertPool([]string{string(server.serverPublicKey)})
if err != nil {
log.Errorf("load root certificate failed, err:%v", err)
return nil, err
}
log.Debugf("load root certificate file successfully")
}
dtlsConf = &piondtls.Config{
Certificates: []tls.Certificate{*cert},
ExtendedMasterSecret: piondtls.RequireExtendedMasterSecret,
RootCAs: rootCertPool,
//InsecureSkipVerify: dtls.InsecureSkipVerify,
}
//case SecurityModePreSharedKey:
//case SecurityModeRawPublicKey:
case SecurityModeNoSec:
// nothing todo
break
default:
return nil, fmt.Errorf("unsupported security mode:%d", server.securityMode)
}
return dtlsConf, nil
}
func dial(client *LwM2MClient, server *ServerInfo) (*MessagerClient, error) {
var dtlsConf *piondtls.Config
var err error
if dtlsConf, err = loadDTLSConfig(client, server); err != nil {
log.Errorf("load dtls config failed: %v", err)
return nil, err
}
messager := NewMessager(client)
if err = messager.Dial(server.address, coap.WithDTLSConfig(dtlsConf)); err != nil {
return nil, err
}
messager.Start()
return messager, nil
}