Files
golib/certificates/cipher/interface.go
Nicolas JUHEL 22b364593e Package certificates:
- rework package to allow convert config to model and retrive config from model
- add sub package to manage cipher, curves, auth client, tls version, certificates, root ca...
- add some small test (can be expande to having more coverage)
- optimize some code

Package httpcli:
- update code following change in certificates

Package httpserver:
- update code following change in certificates

Package Config/Components:
- update code following change in certificates

Package FTPClient:
- update code following change in certificates

Package Nats:
- update code following change in certificates
2024-12-04 17:30:22 +01:00

200 lines
6.2 KiB
Go

/*
* MIT License
*
* Copyright (c) 2020 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package curves
import (
"crypto/tls"
"math"
"slices"
"strings"
)
type Cipher uint16
const (
Unknown Cipher = Cipher(0)
// TLS 1.0 - 1.2 cipher suites.
TLS_RSA_WITH_AES_128_GCM_SHA256 = Cipher(tls.TLS_RSA_WITH_AES_128_GCM_SHA256)
TLS_RSA_WITH_AES_256_GCM_SHA384 = Cipher(tls.TLS_RSA_WITH_AES_256_GCM_SHA384)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = Cipher(tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = Cipher(tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = Cipher(tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = Cipher(tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = Cipher(tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = Cipher(tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
// TLS 1.3 cipher suites.
TLS_AES_128_GCM_SHA256 = Cipher(tls.TLS_AES_128_GCM_SHA256)
TLS_AES_256_GCM_SHA384 = Cipher(tls.TLS_AES_256_GCM_SHA384)
TLS_CHACHA20_POLY1305_SHA256 = Cipher(tls.TLS_CHACHA20_POLY1305_SHA256)
)
func List() []Cipher {
return []Cipher{
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_AES_128_GCM_SHA256,
TLS_AES_256_GCM_SHA384,
TLS_CHACHA20_POLY1305_SHA256,
}
}
func ListString() []string {
var res = make([]string, 0)
for _, c := range List() {
res = append(res, c.String())
}
return res
}
func Parse(s string) Cipher {
s = strings.ToLower(s)
s = strings.Replace(s, "\"", "", -1)
s = strings.Replace(s, "'", "", -1)
s = strings.Replace(s, "tls", "", -1)
s = strings.Replace(s, ".", "_", -1)
s = strings.Replace(s, "-", "_", -1)
s = strings.Replace(s, " ", "_", -1)
s = strings.TrimSpace(s)
p := strings.Split(s, "_")
switch {
case containString(p, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.Code()):
return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
case containString(p, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.Code()):
return TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
case containString(p, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384.Code()):
return TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
case containString(p, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384.Code()):
return TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
case containString(p, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256.Code()):
return TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
case containString(p, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256.Code()):
return TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
case containString(p, TLS_CHACHA20_POLY1305_SHA256.Code()):
return TLS_CHACHA20_POLY1305_SHA256
case containString(p, TLS_RSA_WITH_AES_128_GCM_SHA256.Code()):
return TLS_RSA_WITH_AES_128_GCM_SHA256
case containString(p, TLS_RSA_WITH_AES_256_GCM_SHA384.Code()):
return TLS_RSA_WITH_AES_256_GCM_SHA384
case containString(p, TLS_AES_128_GCM_SHA256.Code()):
return TLS_AES_128_GCM_SHA256
case containString(p, TLS_AES_256_GCM_SHA384.Code()):
return TLS_AES_256_GCM_SHA384
default:
return Unknown
}
}
func containString[S ~[]string](s S, v S) bool {
keys := []string{
"chacha20",
"poly1305",
"ecdhe",
"rsa",
"ecdsa",
"aes",
"128",
"256",
"sha256",
"sha384",
"gcm",
}
for _, k := range keys {
if !keyContainString(s, v, k) {
return false
}
}
return true
}
func keyContainString[S ~[]string](s S, v S, k string) bool {
if slices.Contains(s, k) && !slices.Contains(v, k) {
return false
} else if !slices.Contains(s, k) && slices.Contains(v, k) {
return false
}
return true
}
func ParseInt(d int) Cipher {
if d > math.MaxUint16 {
d = math.MaxUint16
} else if d < 1 {
d = 0
}
switch uint16(d) {
case tls.TLS_RSA_WITH_AES_128_GCM_SHA256:
return TLS_RSA_WITH_AES_128_GCM_SHA256
case tls.TLS_RSA_WITH_AES_256_GCM_SHA384:
return TLS_RSA_WITH_AES_256_GCM_SHA384
case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
case tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
case tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
return TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
case tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
return TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
case tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
return TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
case tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
return TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
case tls.TLS_AES_128_GCM_SHA256:
return TLS_AES_128_GCM_SHA256
case tls.TLS_AES_256_GCM_SHA384:
return TLS_AES_256_GCM_SHA384
case tls.TLS_CHACHA20_POLY1305_SHA256:
return TLS_CHACHA20_POLY1305_SHA256
default:
return Unknown
}
}
func Check(cipher uint16) bool {
if c := ParseInt(int(cipher)); c == Unknown {
return false
}
return true
}
func parseBytes(p []byte) Cipher {
return Parse(string(p))
}