1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 05:40:11 +01:00

Move cert handling into library and add option passphrase. Adjust uploader and checker.

This commit is contained in:
Sascha L. Teichmann 2023-08-02 21:02:58 +02:00
parent 873eb4879b
commit 017a6b0a10
5 changed files with 140 additions and 74 deletions

74
internal/certs/certs.go Normal file
View file

@ -0,0 +1,74 @@
// This file is Free Software under the MIT License
// without warranty, see README.md and LICENSES/MIT.txt for details.
//
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
// Package certs implement helpers for the tools to handle client side certifacates.
package certs
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"os"
)
// LoadCertificate loads an client certificate from file with an optional passphrase.
// Returns nil if no certificate was loaded.
func LoadCertificate(certFile, keyFile, passphrase *string) ([]tls.Certificate, error) {
switch hasCert, hasKey := certFile != nil, keyFile != nil; {
case hasCert && !hasKey || !hasCert && hasKey:
return nil, errors.New(
"both client-key and client-cert options must be set for the authentication")
case hasCert:
// No passphrase
if passphrase == nil {
cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
if err != nil {
return nil, err
}
return []tls.Certificate{cert}, nil
}
// With passphrase
keyFile, err := os.ReadFile(*keyFile)
if err != nil {
return nil, err
}
keyBlock, _ := pem.Decode(keyFile)
//lint:ignore SA1019 This is insecure by design.
keyDER, err := x509.DecryptPEMBlock(keyBlock, []byte(*passphrase))
if err != nil {
return nil, err
}
// Update keyBlock with the plaintext bytes and clear the now obsolete
// headers.
keyBlock.Bytes = keyDER
keyBlock.Headers = nil
// Turn the key back into PEM format so we can leverage tls.X509KeyPair,
// which will deal with the intricacies of error handling, different key
// types, certificate chains, etc
keyPEM := pem.EncodeToMemory(keyBlock)
certPEMBlock, err := os.ReadFile(*certFile)
if err != nil {
return nil, err
}
cert, err := tls.X509KeyPair(certPEMBlock, keyPEM)
if err != nil {
return nil, err
}
return []tls.Certificate{cert}, nil
}
return nil, nil
}