aws_signing_helper/file_system_signer.go (134 lines of code) (raw):

package aws_signing_helper import ( "crypto" "crypto/ecdsa" "crypto/rsa" "crypto/sha256" "crypto/sha512" "crypto/x509" "errors" "io" "log" "os" ) type FileSystemSigner struct { bundlePath string certPath string isPkcs12 bool privateKeyPath string } func (fileSystemSigner *FileSystemSigner) Public() crypto.PublicKey { privateKey, _, _ := fileSystemSigner.readCertFiles() { privateKey, ok := privateKey.(*ecdsa.PrivateKey) if ok { return &privateKey.PublicKey } } { privateKey, ok := privateKey.(*rsa.PrivateKey) if ok { return &privateKey.PublicKey } } return nil } func (fileSystemSigner *FileSystemSigner) Close() {} func (fileSystemSigner *FileSystemSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { privateKey, _, _ := fileSystemSigner.readCertFiles() var hash []byte switch opts.HashFunc() { case crypto.SHA256: sum := sha256.Sum256(digest) hash = sum[:] case crypto.SHA384: sum := sha512.Sum384(digest) hash = sum[:] case crypto.SHA512: sum := sha512.Sum512(digest) hash = sum[:] default: return nil, ErrUnsupportedHash } ecdsaPrivateKey, ok := privateKey.(*ecdsa.PrivateKey) if ok { sig, err := ecdsa.SignASN1(rand, ecdsaPrivateKey, hash[:]) if err == nil { return sig, nil } } rsaPrivateKey, ok := privateKey.(*rsa.PrivateKey) if ok { sig, err := rsa.SignPKCS1v15(rand, rsaPrivateKey, opts.HashFunc(), hash[:]) if err == nil { return sig, nil } } log.Println("unsupported algorithm") return nil, errors.New("unsupported algorithm") } func (fileSystemSigner *FileSystemSigner) Certificate() (*x509.Certificate, error) { _, cert, _ := fileSystemSigner.readCertFiles() return cert, nil } func (fileSystemSigner *FileSystemSigner) CertificateChain() ([]*x509.Certificate, error) { _, _, certChain := fileSystemSigner.readCertFiles() return certChain, nil } // GetFileSystemSigner returns a FileSystemSigner, that signs a payload using the private key passed in func GetFileSystemSigner(privateKeyPath string, certPath string, bundlePath string, isPkcs12 bool) (signer Signer, signingAlgorithm string, err error) { fsSigner := &FileSystemSigner{bundlePath: bundlePath, certPath: certPath, isPkcs12: isPkcs12, privateKeyPath: privateKeyPath} privateKey, _, _ := fsSigner.readCertFiles() // Find the signing algorithm _, isRsaKey := privateKey.(*rsa.PrivateKey) if isRsaKey { signingAlgorithm = aws4_x509_rsa_sha256 } _, isEcKey := privateKey.(*ecdsa.PrivateKey) if isEcKey { signingAlgorithm = aws4_x509_ecdsa_sha256 } if signingAlgorithm == "" { log.Println("unsupported algorithm") return nil, "", errors.New("unsupported algorithm") } return fsSigner, signingAlgorithm, nil } func (fileSystemSigner *FileSystemSigner) readCertFiles() (crypto.PrivateKey, *x509.Certificate, []*x509.Certificate) { if fileSystemSigner.isPkcs12 { chain, privateKey, err := ReadPKCS12Data(fileSystemSigner.certPath) if err != nil { log.Printf("Failed to read PKCS12 certificate: %s\n", err) os.Exit(1) } return privateKey, chain[0], chain } else { privateKey, err := ReadPrivateKeyData(fileSystemSigner.privateKeyPath) if err != nil { log.Printf("Failed to read private key: %s\n", err) os.Exit(1) } var chain []*x509.Certificate if fileSystemSigner.bundlePath != "" { chain, err = GetCertChain(fileSystemSigner.bundlePath) if err != nil { privateKey = nil log.Printf("Failed to read certificate bundle: %s\n", err) os.Exit(1) } } var cert *x509.Certificate if fileSystemSigner.certPath != "" { _, cert, err = ReadCertificateData(fileSystemSigner.certPath) if err != nil { privateKey = nil log.Printf("Failed to read certificate: %s\n", err) os.Exit(1) } } else if len(chain) > 0 { cert = chain[0] } else { log.Println("No certificate path or certificate bundle path provided") os.Exit(1) } return privateKey, cert, chain } }