-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathtls_config.go
108 lines (90 loc) · 3.63 KB
/
tls_config.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
package iec61850
// #include <tls_config.h>
import "C"
import (
"fmt"
"unsafe"
)
type TLSConfigVersion int
const (
TLS_VERSION_NOT_SELECTED TLSConfigVersion = 0
TLS_VERSION_SSL_3_0 = 3
TLS_VERSION_TLS_1_0 = 4
TLS_VERSION_TLS_1_1 = 5
TLS_VERSION_TLS_1_2 = 6
TLS_VERSION_TLS_1_3 = 7
)
type TLSConfigurationEventHandler func(parameter unsafe.Pointer, eventLevel, eventCode int, message string, conn C.TLSConnection)
type TLSConfig struct {
KeyFile string // Path to the key file
KeyPassword string // Password for the key file
CertFile string // Path to the certificate file
ChainValidation bool // Enable chain validation
AllowOnlyKnownCertificates bool // Allow only known certificates
MinTlsVersion TLSConfigVersion
MaxTlsVersion TLSConfigVersion
caCerts []string
allowedCertificates []string
tlsConfigurationEventHandler *TLSConfigurationEventHandler
}
func NewTLSConfig() *TLSConfig {
return &TLSConfig{
ChainValidation: true,
AllowOnlyKnownCertificates: false,
MinTlsVersion: TLS_VERSION_TLS_1_0,
MaxTlsVersion: TLS_VERSION_NOT_SELECTED,
caCerts: make([]string, 0),
allowedCertificates: make([]string, 0),
}
}
func (that *TLSConfig) AddCACertificateFromFile(filename string) {
that.caCerts = append(that.caCerts, filename)
}
func (that *TLSConfig) AddAllowedCertificateFromFile(filename string) {
that.allowedCertificates = append(that.allowedCertificates, filename)
}
func (that *TLSConfig) SetEventHandler(handler *TLSConfigurationEventHandler) {
that.tlsConfigurationEventHandler = handler
}
func (that *TLSConfig) createCTlsConfig() (C.TLSConfiguration, error) {
cKeyFile := C.CString(that.KeyFile)
defer C.free(unsafe.Pointer(cKeyFile))
cKeyPassword := C.CString(that.KeyPassword)
defer C.free(unsafe.Pointer(cKeyPassword))
cCertFile := C.CString(that.CertFile)
defer C.free(unsafe.Pointer(cCertFile))
tlsConfig := C.TLSConfiguration_create()
C.TLSConfiguration_setChainValidation(tlsConfig, C.bool(that.ChainValidation))
C.TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig, C.bool(that.AllowOnlyKnownCertificates))
C.TLSConfiguration_setMinTlsVersion(tlsConfig, C.TLSConfigVersion(that.MinTlsVersion))
C.TLSConfiguration_setMaxTlsVersion(tlsConfig, C.TLSConfigVersion(that.MaxTlsVersion))
if that.KeyPassword == "" {
if !bool(C.TLSConfiguration_setOwnKeyFromFile(tlsConfig, cKeyFile, nil)) {
return nil, fmt.Errorf("failed to load private key %s", that.KeyFile)
}
} else {
if !bool(C.TLSConfiguration_setOwnKeyFromFile(tlsConfig, cKeyFile, cKeyPassword)) {
return nil, fmt.Errorf("failed to load private key %s", that.KeyFile)
}
}
if !bool(C.TLSConfiguration_setOwnCertificateFromFile(tlsConfig, cCertFile)) {
return nil, fmt.Errorf("failed to load own certificate %s", that.CertFile)
}
for _, caCert := range that.caCerts {
cCACert := C.CString(caCert)
if !bool(C.TLSConfiguration_addCACertificateFromFile(tlsConfig, cCACert)) {
C.free(unsafe.Pointer(cCACert))
return nil, fmt.Errorf("failed to load CA certificate %s", caCert)
}
C.free(unsafe.Pointer(cCACert))
}
for _, cert := range that.allowedCertificates {
cCert := C.CString(cert)
if !bool(C.TLSConfiguration_addAllowedCertificateFromFile(tlsConfig, cCert)) {
C.free(unsafe.Pointer(cCert))
return nil, fmt.Errorf("failed to load allowed certificate %s", cert)
}
C.free(unsafe.Pointer(cCert))
}
return tlsConfig, nil
}