Files
cloud-services/pkg/utils/certificate_parser.go

58 lines
1.4 KiB
Go

package utils
import (
"fmt"
"net/http"
"strings"
"fiskerinc.com/modules/logger"
"fiskerinc.com/modules/validator"
)
// ParseVINFromRequest retrieves VIN from "Ssl-Client-Subject-Dn"
//
// which is generated by NGINX through a cert on websocket request
func ParseVINFromRequest(r *http.Request) (vin string, err error) {
// Try SDK 1.2 format first: Ssl-Client-Subject-Dn header
vin = retrieveCommonNameFromHeaderSSLClientSubject(r)
if vin == "" {
// Try SDK 1.4 format: Ssl header
vin = retrieveCommonNameFromHeaderSSL(r)
}
ok := validator.ValidateVINSimple(vin)
if ok {
return vin, nil
}
// If neither header format contains a VIN, return error
return "", fmt.Errorf("VIN not found in request headers: '%s' bad value", vin)
}
func retrieveCommonNameFromHeaderSSL(r *http.Request) (vin string) {
sslHeader := r.Header.Get("Ssl")
logger.Info().Str("SSL Header Value", sslHeader).Msg("CSDK 1.2 VIN Format Failed, trying 1.4")
if sslHeader != "" {
// Extract VIN from "CN=VIN_HERE" format
if strings.HasPrefix(sslHeader, "CN=") {
vin = strings.TrimPrefix(sslHeader, "CN=")
}
}
return
}
func retrieveCommonNameFromHeaderSSLClientSubject(r *http.Request) string {
dn := r.Header.Values("Ssl-Client-Subject-Dn")
for _, d := range dn {
fields := strings.Split(d, ",")
for _, field := range fields {
if len(field) > 3 && field[:3] == "CN=" {
return field[3:]
}
}
}
return ""
}