You've already forked aws-iam-anywhere-refresher
this is my quickfix branch and i will use to do my quickfixes
This commit is contained in:
@@ -1 +1,5 @@
|
|||||||
.idea/
|
.idea/
|
||||||
|
.gitea/
|
||||||
|
aws-iam-anywhere-refresher
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
FROM siteworxpro/golang:1.24.3 AS build
|
FROM siteworxpro/golang:1.24.3 AS build
|
||||||
|
|
||||||
ENV GOPRIVATE=git.siteworxpro.com
|
|
||||||
ENV GOPROXY=direct
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ADD . .
|
ADD . .
|
||||||
|
|
||||||
RUN go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -o /app/aws-iam-anywhere-refresher
|
ENV GOPRIVATE=git.siteworxpro.com
|
||||||
|
ENV CGO_ENABLED=0
|
||||||
|
|
||||||
|
RUN go mod tidy && go build -o aws-iam-anywhere-refresher .
|
||||||
|
|
||||||
FROM alpine:latest AS runtime
|
FROM alpine:latest AS runtime
|
||||||
|
|
||||||
|
|||||||
@@ -176,9 +176,9 @@ func GetCertStoreSigner(certIdentifier CertIdentifier, useLatestExpiringCert boo
|
|||||||
// Find the signing algorithm
|
// Find the signing algorithm
|
||||||
switch cert.PublicKey.(type) {
|
switch cert.PublicKey.(type) {
|
||||||
case *ecdsa.PublicKey:
|
case *ecdsa.PublicKey:
|
||||||
signingAlgorithm = aws4_x509_ecdsa_sha256
|
signingAlgorithm = aws4X509EcdsaSha256
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
signingAlgorithm = aws4_x509_rsa_sha256
|
signingAlgorithm = aws4X509RsaSha256
|
||||||
default:
|
default:
|
||||||
err = errors.New("unsupported algorithm")
|
err = errors.New("unsupported algorithm")
|
||||||
goto fail
|
goto fail
|
||||||
|
|||||||
@@ -94,11 +94,11 @@ func GetFileSystemSigner(privateKeyPath string, certPath string, bundlePath stri
|
|||||||
// Find the signing algorithm
|
// Find the signing algorithm
|
||||||
_, isRsaKey := privateKey.(*rsa.PrivateKey)
|
_, isRsaKey := privateKey.(*rsa.PrivateKey)
|
||||||
if isRsaKey {
|
if isRsaKey {
|
||||||
signingAlgorithm = aws4_x509_rsa_sha256
|
signingAlgorithm = aws4X509RsaSha256
|
||||||
}
|
}
|
||||||
_, isEcKey := privateKey.(*ecdsa.PrivateKey)
|
_, isEcKey := privateKey.(*ecdsa.PrivateKey)
|
||||||
if isEcKey {
|
if isEcKey {
|
||||||
signingAlgorithm = aws4_x509_ecdsa_sha256
|
signingAlgorithm = aws4X509EcdsaSha256
|
||||||
}
|
}
|
||||||
if signingAlgorithm == "" {
|
if signingAlgorithm == "" {
|
||||||
log.Println("unsupported algorithm")
|
log.Println("unsupported algorithm")
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -47,13 +46,12 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/miekg/pkcs11"
|
"github.com/miekg/pkcs11"
|
||||||
pkcs11uri "github.com/stefanberger/go-pkcs11uri"
|
"github.com/stefanberger/go-pkcs11uri"
|
||||||
)
|
)
|
||||||
|
|
||||||
var PKCS11_TEST_VERSION int16 = 1
|
var Pkcs11TestVersion int16 = 1
|
||||||
var MAX_OBJECT_LIMIT int = 1000
|
var MaxObjectLimit int = 1000
|
||||||
|
|
||||||
// In our list of certs, we want to remember the CKA_ID/CKA_LABEL too.
|
|
||||||
type CertObjInfo struct {
|
type CertObjInfo struct {
|
||||||
id []byte
|
id []byte
|
||||||
label []byte
|
label []byte
|
||||||
@@ -61,14 +59,12 @@ type CertObjInfo struct {
|
|||||||
certObject pkcs11.ObjectHandle
|
certObject pkcs11.ObjectHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
// In our list of keys, we want to remember the CKA_ID/CKA_LABEL too.
|
|
||||||
type KeyObjInfo struct {
|
type KeyObjInfo struct {
|
||||||
id []byte
|
id []byte
|
||||||
label []byte
|
label []byte
|
||||||
keyObject pkcs11.ObjectHandle
|
keyObject pkcs11.ObjectHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to enumerate slots with all token/slot info for matching.
|
|
||||||
type SlotIdInfo struct {
|
type SlotIdInfo struct {
|
||||||
id uint
|
id uint
|
||||||
info pkcs11.SlotInfo
|
info pkcs11.SlotInfo
|
||||||
@@ -114,7 +110,7 @@ func initializePKCS11Module(lib string) (module *pkcs11.Ctx, err error) {
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
if module != nil {
|
if module != nil {
|
||||||
module.Finalize()
|
_ = module.Finalize()
|
||||||
module.Destroy()
|
module.Destroy()
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -137,18 +133,10 @@ func enumerateSlotsInPKCS11Module(module *pkcs11.Ctx) (slots []SlotIdInfo, err e
|
|||||||
slotIdInfo.id = slotId
|
slotIdInfo.id = slotId
|
||||||
slotIdInfo.info, slotErr = module.GetSlotInfo(slotId)
|
slotIdInfo.info, slotErr = module.GetSlotInfo(slotId)
|
||||||
if slotErr != nil {
|
if slotErr != nil {
|
||||||
if Debug {
|
|
||||||
log.Printf("unable to get slot info for slot %d"+
|
|
||||||
" (%s)\n", slotId, slotErr)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
slotIdInfo.tokInfo, slotErr = module.GetTokenInfo(slotId)
|
slotIdInfo.tokInfo, slotErr = module.GetTokenInfo(slotId)
|
||||||
if slotErr != nil {
|
if slotErr != nil {
|
||||||
if Debug {
|
|
||||||
log.Printf("unable to get token info for slot %d"+
|
|
||||||
" (%s)\n", slotId, slotErr)
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +218,7 @@ func getFindTemplate(uri *pkcs11uri.Pkcs11URI, class uint) (template []*pkcs11.A
|
|||||||
|
|
||||||
// Gets certificate(s) within the PKCS#11 session (i.e. a given token) that
|
// Gets certificate(s) within the PKCS#11 session (i.e. a given token) that
|
||||||
// matches the given URI.
|
// matches the given URI.
|
||||||
func getCertsInSession(module *pkcs11.Ctx, slotId uint, session pkcs11.SessionHandle, uri *pkcs11uri.Pkcs11URI) (certs []CertObjInfo, err error) {
|
func getCertsInSession(module *pkcs11.Ctx, _ uint, session pkcs11.SessionHandle, uri *pkcs11uri.Pkcs11URI) (certs []CertObjInfo, err error) {
|
||||||
var (
|
var (
|
||||||
sessionCertObjects []pkcs11.ObjectHandle
|
sessionCertObjects []pkcs11.ObjectHandle
|
||||||
certObjects []pkcs11.ObjectHandle
|
certObjects []pkcs11.ObjectHandle
|
||||||
@@ -245,7 +233,7 @@ func getCertsInSession(module *pkcs11.Ctx, slotId uint, session pkcs11.SessionHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
for true {
|
for true {
|
||||||
sessionCertObjects, _, err = module.FindObjects(session, MAX_OBJECT_LIMIT)
|
sessionCertObjects, _, err = module.FindObjects(session, MaxObjectLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -253,7 +241,7 @@ func getCertsInSession(module *pkcs11.Ctx, slotId uint, session pkcs11.SessionHa
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
certObjects = append(certObjects, sessionCertObjects...)
|
certObjects = append(certObjects, sessionCertObjects...)
|
||||||
if len(sessionCertObjects) < MAX_OBJECT_LIMIT {
|
if len(sessionCertObjects) < MaxObjectLimit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,11 +323,7 @@ func getMatchingCerts(module *pkcs11.Ctx, slots []SlotIdInfo, uri *pkcs11uri.Pkc
|
|||||||
for _, slot := range slots {
|
for _, slot := range slots {
|
||||||
curSession, err := module.OpenSession(slot.id, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKS_RO_PUBLIC_SESSION)
|
curSession, err := module.OpenSession(slot.id, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKS_RO_PUBLIC_SESSION)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if Debug {
|
_ = module.CloseSession(curSession)
|
||||||
log.Printf("unable to open session in slot %d"+
|
|
||||||
" (%s)\n", slot.id, err)
|
|
||||||
}
|
|
||||||
module.CloseSession(curSession)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +338,7 @@ func getMatchingCerts(module *pkcs11.Ctx, slots []SlotIdInfo, uri *pkcs11uri.Pkc
|
|||||||
goto skipCloseSession
|
goto skipCloseSession
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.CloseSession(curSession)
|
_ = module.CloseSession(curSession)
|
||||||
skipCloseSession:
|
skipCloseSession:
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,86 +406,12 @@ foundCert:
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
if session != 0 {
|
if session != 0 {
|
||||||
module.Logout(session)
|
_ = module.Logout(session)
|
||||||
module.CloseSession(session)
|
_ = module.CloseSession(session)
|
||||||
}
|
}
|
||||||
return SlotIdInfo{}, session, false, nil, err
|
return SlotIdInfo{}, session, false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to implement a cut-down version of `p11tool --list-certificates`.
|
|
||||||
func GetMatchingPKCSCerts(uriStr string, lib string) (matchingCerts []CertificateContainer, err error) {
|
|
||||||
var (
|
|
||||||
slots []SlotIdInfo
|
|
||||||
module *pkcs11.Ctx
|
|
||||||
uri *pkcs11uri.Pkcs11URI
|
|
||||||
userPin string
|
|
||||||
certObjs []CertObjInfo
|
|
||||||
session pkcs11.SessionHandle
|
|
||||||
loggedIn bool
|
|
||||||
slot SlotIdInfo
|
|
||||||
)
|
|
||||||
|
|
||||||
uri = pkcs11uri.New()
|
|
||||||
err = uri.Parse(uriStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userPin, _ = uri.GetQueryAttribute("pin-value", false)
|
|
||||||
|
|
||||||
module, err = initializePKCS11Module(lib)
|
|
||||||
if err != nil {
|
|
||||||
goto cleanUp
|
|
||||||
}
|
|
||||||
|
|
||||||
slots, err = enumerateSlotsInPKCS11Module(module)
|
|
||||||
if err != nil {
|
|
||||||
goto cleanUp
|
|
||||||
}
|
|
||||||
|
|
||||||
slot, session, loggedIn, certObjs, err = getMatchingCerts(module, slots, uri, userPin, false)
|
|
||||||
if err != nil {
|
|
||||||
goto cleanUp
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, obj := range certObjs {
|
|
||||||
curUri := pkcs11uri.New()
|
|
||||||
curUri.AddPathAttribute("model", slot.tokInfo.Model)
|
|
||||||
curUri.AddPathAttribute("manufacturer", slot.tokInfo.ManufacturerID)
|
|
||||||
curUri.AddPathAttribute("serial", slot.tokInfo.SerialNumber)
|
|
||||||
curUri.AddPathAttribute("slot-description", slot.info.SlotDescription)
|
|
||||||
curUri.AddPathAttribute("slot-manufacturer", slot.info.ManufacturerID)
|
|
||||||
if obj.id != nil {
|
|
||||||
curUri.AddPathAttribute("id", string(obj.id[:]))
|
|
||||||
}
|
|
||||||
if obj.label != nil {
|
|
||||||
curUri.AddPathAttribute("object", string(obj.label[:]))
|
|
||||||
}
|
|
||||||
curUri.AddPathAttribute("type", "cert")
|
|
||||||
curUriStr, err := curUri.Format() // nosemgrep
|
|
||||||
if err != nil {
|
|
||||||
curUriStr = ""
|
|
||||||
}
|
|
||||||
matchingCerts = append(matchingCerts, CertificateContainer{-1, obj.cert, curUriStr})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that this clean up should happen regardless of failure.
|
|
||||||
cleanUp:
|
|
||||||
if module != nil {
|
|
||||||
if session != 0 {
|
|
||||||
if loggedIn {
|
|
||||||
module.Logout(session)
|
|
||||||
}
|
|
||||||
module.CloseSession(session)
|
|
||||||
}
|
|
||||||
module.Finalize()
|
|
||||||
module.Destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingCerts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the public key associated with this PKCS11Signer.
|
|
||||||
func (pkcs11Signer *PKCS11Signer) Public() crypto.PublicKey {
|
func (pkcs11Signer *PKCS11Signer) Public() crypto.PublicKey {
|
||||||
var (
|
var (
|
||||||
cert *x509.Certificate
|
cert *x509.Certificate
|
||||||
@@ -522,14 +432,13 @@ func (pkcs11Signer *PKCS11Signer) Public() crypto.PublicKey {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closes this PKCS11Signer.
|
|
||||||
func (pkcs11Signer *PKCS11Signer) Close() {
|
func (pkcs11Signer *PKCS11Signer) Close() {
|
||||||
var module *pkcs11.Ctx
|
var module *pkcs11.Ctx
|
||||||
|
|
||||||
module = pkcs11Signer.module
|
module = pkcs11Signer.module
|
||||||
|
|
||||||
if module != nil {
|
if module != nil {
|
||||||
module.Finalize()
|
_ = module.Finalize()
|
||||||
module.Destroy()
|
module.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,13 +474,17 @@ func pkcs11PasswordPrompt(module *pkcs11.Ctx, session pkcs11.SessionHandle, user
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New(parseErrMsg)
|
return "", errors.New(parseErrMsg)
|
||||||
}
|
}
|
||||||
defer ttyReadFile.Close()
|
defer func(ttyReadFile *os.File) {
|
||||||
|
_ = ttyReadFile.Close()
|
||||||
|
}(ttyReadFile)
|
||||||
|
|
||||||
ttyWriteFile, err = os.OpenFile(ttyWritePath, os.O_WRONLY, 0)
|
ttyWriteFile, err = os.OpenFile(ttyWritePath, os.O_WRONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New(parseErrMsg)
|
return "", errors.New(parseErrMsg)
|
||||||
}
|
}
|
||||||
defer ttyWriteFile.Close()
|
defer func(ttyWriteFile *os.File) {
|
||||||
|
_ = ttyWriteFile.Close()
|
||||||
|
}(ttyWriteFile)
|
||||||
|
|
||||||
for true {
|
for true {
|
||||||
pin, err = GetPassword(ttyReadFile, ttyWriteFile, prompt, parseErrMsg)
|
pin, err = GetPassword(ttyReadFile, ttyWriteFile, prompt, parseErrMsg)
|
||||||
@@ -654,28 +567,24 @@ func signHelper(module *pkcs11.Ctx, session pkcs11.SessionHandle, privateKeyObj
|
|||||||
err = module.Login(session, pkcs11.CKU_CONTEXT_SPECIFIC, contextSpecificPin)
|
err = module.Login(session, pkcs11.CKU_CONTEXT_SPECIFIC, contextSpecificPin)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
goto afterContextSpecificLogin
|
goto afterContextSpecificLogin
|
||||||
} else {
|
|
||||||
if Debug {
|
|
||||||
log.Printf("user re-authentication attempt failed (%s)\n", err.Error())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the context-specific PIN couldn't be derived, prompt the user for
|
// If the context-specific PIN couldn't be derived, prompt the user for
|
||||||
// the context-specific PIN for this object.
|
// the context-specific PIN for this object.
|
||||||
keyUri = pkcs11uri.New()
|
keyUri = pkcs11uri.New()
|
||||||
keyUri.AddPathAttribute("model", slot.tokInfo.Model)
|
_ = keyUri.AddPathAttribute("model", slot.tokInfo.Model)
|
||||||
keyUri.AddPathAttribute("manufacturer", slot.tokInfo.ManufacturerID)
|
_ = keyUri.AddPathAttribute("manufacturer", slot.tokInfo.ManufacturerID)
|
||||||
keyUri.AddPathAttribute("serial", slot.tokInfo.SerialNumber)
|
_ = keyUri.AddPathAttribute("serial", slot.tokInfo.SerialNumber)
|
||||||
keyUri.AddPathAttribute("slot-description", slot.info.SlotDescription)
|
_ = keyUri.AddPathAttribute("slot-description", slot.info.SlotDescription)
|
||||||
keyUri.AddPathAttribute("slot-manufacturer", slot.info.ManufacturerID)
|
_ = keyUri.AddPathAttribute("slot-manufacturer", slot.info.ManufacturerID)
|
||||||
if privateKeyObj.id != nil {
|
if privateKeyObj.id != nil {
|
||||||
keyUri.AddPathAttribute("id", string(privateKeyObj.id[:]))
|
_ = keyUri.AddPathAttribute("id", string(privateKeyObj.id[:]))
|
||||||
}
|
}
|
||||||
if privateKeyObj.label != nil {
|
if privateKeyObj.label != nil {
|
||||||
keyUri.AddPathAttribute("object", string(privateKeyObj.label[:]))
|
_ = keyUri.AddPathAttribute("object", string(privateKeyObj.label[:]))
|
||||||
}
|
}
|
||||||
keyUri.AddPathAttribute("type", "private")
|
_ = keyUri.AddPathAttribute("type", "private")
|
||||||
keyUriStr, err = keyUri.Format() // nosemgrep
|
keyUriStr, err = keyUri.Format() // nosemgrep
|
||||||
if err != nil {
|
if err != nil {
|
||||||
keyUriStr = ""
|
keyUriStr = ""
|
||||||
@@ -737,17 +646,14 @@ func getPKCS11Key(module *pkcs11.Ctx, session pkcs11.SessionHandle, loggedIn boo
|
|||||||
manufacturerId = slots[0].info.ManufacturerID
|
manufacturerId = slots[0].info.ManufacturerID
|
||||||
if session != 0 {
|
if session != 0 {
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
module.Logout(session)
|
_ = module.Logout(session)
|
||||||
module.CloseSession(session)
|
_ = module.CloseSession(session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loggedIn = false
|
loggedIn = false
|
||||||
session = 0
|
session = 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Debug {
|
|
||||||
log.Printf("Found %d matching slots for the PKCS#11 key\n", len(slots))
|
|
||||||
}
|
|
||||||
// If the URI matched multiple slots *but* one of them is the
|
// If the URI matched multiple slots *but* one of them is the
|
||||||
// one (certSlotNr) that the certificate was found in, then use
|
// one (certSlotNr) that the certificate was found in, then use
|
||||||
// that.
|
// that.
|
||||||
@@ -794,7 +700,7 @@ retry_search:
|
|||||||
goto fail
|
goto fail
|
||||||
}
|
}
|
||||||
for true {
|
for true {
|
||||||
sessionPrivateKeyObjects, _, err := module.FindObjects(session, MAX_OBJECT_LIMIT)
|
sessionPrivateKeyObjects, _, err := module.FindObjects(session, MaxObjectLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
goto fail
|
goto fail
|
||||||
}
|
}
|
||||||
@@ -802,7 +708,7 @@ retry_search:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
privateKeyObjects = append(privateKeyObjects, sessionPrivateKeyObjects...)
|
privateKeyObjects = append(privateKeyObjects, sessionPrivateKeyObjects...)
|
||||||
if len(sessionPrivateKeyObjects) < MAX_OBJECT_LIMIT {
|
if len(sessionPrivateKeyObjects) < MaxObjectLimit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -894,13 +800,8 @@ retry_search:
|
|||||||
if noKeyUri {
|
if noKeyUri {
|
||||||
_, keyHadLabel := keyUri.GetPathAttribute("object", false)
|
_, keyHadLabel := keyUri.GetPathAttribute("object", false)
|
||||||
if keyHadLabel {
|
if keyHadLabel {
|
||||||
if Debug {
|
|
||||||
log.Println("unable to find private key with CKA_LABEL;" +
|
|
||||||
" repeating the search using CKA_ID of the certificate" +
|
|
||||||
" without requiring a CKA_LABEL match")
|
|
||||||
}
|
|
||||||
keyUri.RemovePathAttribute("object")
|
keyUri.RemovePathAttribute("object")
|
||||||
keyUri.SetPathAttribute("id", escapeAll(certObj.id))
|
_ = keyUri.SetPathAttribute("id", escapeAll(certObj.id))
|
||||||
goto retry_search
|
goto retry_search
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -913,10 +814,10 @@ retry_search:
|
|||||||
// So that hunting for the key can be more efficient in the future,
|
// So that hunting for the key can be more efficient in the future,
|
||||||
// return a key URI that has CKA_ID and CKA_LABEL appropriately set.
|
// return a key URI that has CKA_ID and CKA_LABEL appropriately set.
|
||||||
if privateKeyObj.id != nil && len(privateKeyObj.id) != 0 {
|
if privateKeyObj.id != nil && len(privateKeyObj.id) != 0 {
|
||||||
keyUri.SetPathAttribute("id", escapeAll(privateKeyObj.id))
|
_ = keyUri.SetPathAttribute("id", escapeAll(privateKeyObj.id))
|
||||||
}
|
}
|
||||||
if privateKeyObj.label != nil && len(privateKeyObj.label) != 0 {
|
if privateKeyObj.label != nil && len(privateKeyObj.label) != 0 {
|
||||||
keyUri.SetPathAttribute("object", escapeAll(privateKeyObj.label))
|
_ = keyUri.SetPathAttribute("object", escapeAll(privateKeyObj.label))
|
||||||
}
|
}
|
||||||
|
|
||||||
return session, userPin, keyUri, keyType, privateKeyObj, keySlot, alwaysAuth, contextSpecificPin, nil
|
return session, userPin, keyUri, keyType, privateKeyObj, keySlot, alwaysAuth, contextSpecificPin, nil
|
||||||
@@ -947,8 +848,7 @@ func getCertificate(module *pkcs11.Ctx, certUri *pkcs11uri.Pkcs11URI, userPin st
|
|||||||
return certSlot, slots, session, loggedIn, matchingCerts[0], nil
|
return certSlot, slots, session, loggedIn, matchingCerts[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements the crypto.Signer interface and signs the passed in digest
|
func (pkcs11Signer *PKCS11Signer) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||||
func (pkcs11Signer *PKCS11Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
|
||||||
var (
|
var (
|
||||||
module *pkcs11.Ctx
|
module *pkcs11.Ctx
|
||||||
session pkcs11.SessionHandle
|
session pkcs11.SessionHandle
|
||||||
@@ -1012,15 +912,14 @@ func (pkcs11Signer *PKCS11Signer) Sign(rand io.Reader, digest []byte, opts crypt
|
|||||||
cleanUp:
|
cleanUp:
|
||||||
if session != 0 {
|
if session != 0 {
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
module.Logout(session)
|
_ = module.Logout(session)
|
||||||
}
|
}
|
||||||
module.CloseSession(session)
|
_ = module.CloseSession(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signature, err
|
return signature, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the *x509.Certificate associated with this PKCS11Signer.
|
|
||||||
func (pkcs11Signer *PKCS11Signer) Certificate() (cert *x509.Certificate, err error) {
|
func (pkcs11Signer *PKCS11Signer) Certificate() (cert *x509.Certificate, err error) {
|
||||||
// If there was a certificate chain associated with this Signer, it
|
// If there was a certificate chain associated with this Signer, it
|
||||||
// should've been saved before.
|
// should've been saved before.
|
||||||
@@ -1123,7 +1022,7 @@ func checkPrivateKeyMatchesCert(module *pkcs11.Ctx, session pkcs11.SessionHandle
|
|||||||
// "AWS Roles Anywhere Credential Helper PKCS11 Test" || PKCS11_TEST_VERSION ||
|
// "AWS Roles Anywhere Credential Helper PKCS11 Test" || PKCS11_TEST_VERSION ||
|
||||||
// MANUFACTURER_ID || SHA256("IAM RA" || PUBLIC_KEY_BYTE_ARRAY)
|
// MANUFACTURER_ID || SHA256("IAM RA" || PUBLIC_KEY_BYTE_ARRAY)
|
||||||
digest := "AWS Roles Anywhere Credential Helper PKCS11 Test" +
|
digest := "AWS Roles Anywhere Credential Helper PKCS11 Test" +
|
||||||
strconv.Itoa(int(PKCS11_TEST_VERSION)) + manufacturerId + string(digestSuffix)
|
strconv.Itoa(int(Pkcs11TestVersion)) + manufacturerId + string(digestSuffix)
|
||||||
digestBytes := []byte(digest)
|
digestBytes := []byte(digest)
|
||||||
hash := sha256.Sum256(digestBytes)
|
hash := sha256.Sum256(digestBytes)
|
||||||
|
|
||||||
@@ -1240,7 +1139,7 @@ func GetPKCS11Signer(libPkcs11 string, cert *x509.Certificate, certChain []*x509
|
|||||||
}
|
}
|
||||||
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
|
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
certUri.SetPathAttribute("id", escapeAll(crtAttributes[0].Value))
|
_ = certUri.SetPathAttribute("id", escapeAll(crtAttributes[0].Value))
|
||||||
}
|
}
|
||||||
|
|
||||||
crtAttributes = []*pkcs11.Attribute{
|
crtAttributes = []*pkcs11.Attribute{
|
||||||
@@ -1248,7 +1147,7 @@ func GetPKCS11Signer(libPkcs11 string, cert *x509.Certificate, certChain []*x509
|
|||||||
}
|
}
|
||||||
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
|
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
certUri.SetPathAttribute("object", escapeAll(crtAttributes[0].Value))
|
_ = certUri.SetPathAttribute("object", escapeAll(crtAttributes[0].Value))
|
||||||
}
|
}
|
||||||
|
|
||||||
if certChain == nil {
|
if certChain == nil {
|
||||||
@@ -1274,7 +1173,7 @@ func GetPKCS11Signer(libPkcs11 string, cert *x509.Certificate, certChain []*x509
|
|||||||
} else {
|
} else {
|
||||||
certUriStr, _ := certUri.Format()
|
certUriStr, _ := certUri.Format()
|
||||||
keyUri = pkcs11uri.New()
|
keyUri = pkcs11uri.New()
|
||||||
keyUri.Parse(certUriStr)
|
_ = keyUri.Parse(certUriStr)
|
||||||
noKeyUri = true
|
noKeyUri = true
|
||||||
}
|
}
|
||||||
if _userPin, ok := keyUri.GetQueryAttribute("pin-value", false); ok {
|
if _userPin, ok := keyUri.GetQueryAttribute("pin-value", false); ok {
|
||||||
@@ -1296,18 +1195,18 @@ func GetPKCS11Signer(libPkcs11 string, cert *x509.Certificate, certChain []*x509
|
|||||||
|
|
||||||
switch keyType {
|
switch keyType {
|
||||||
case pkcs11.CKK_EC:
|
case pkcs11.CKK_EC:
|
||||||
signingAlgorithm = aws4_x509_ecdsa_sha256
|
signingAlgorithm = aws4X509EcdsaSha256
|
||||||
case pkcs11.CKK_RSA:
|
case pkcs11.CKK_RSA:
|
||||||
signingAlgorithm = aws4_x509_rsa_sha256
|
signingAlgorithm = aws4X509RsaSha256
|
||||||
default:
|
default:
|
||||||
return nil, "", errors.New("unsupported algorithm")
|
return nil, "", errors.New("unsupported algorithm")
|
||||||
}
|
}
|
||||||
|
|
||||||
if session != 0 {
|
if session != 0 {
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
module.Logout(session)
|
_ = module.Logout(session)
|
||||||
}
|
}
|
||||||
module.CloseSession(session)
|
_ = module.CloseSession(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PKCS11Signer{cert, certChain, module, userPin, alwaysAuth, contextSpecificPin, certUri, keyUri, reusePin}, signingAlgorithm, nil
|
return &PKCS11Signer{cert, certChain, module, userPin, alwaysAuth, contextSpecificPin, certUri, keyUri, reusePin}, signingAlgorithm, nil
|
||||||
@@ -1316,11 +1215,11 @@ fail:
|
|||||||
if module != nil {
|
if module != nil {
|
||||||
if session != 0 {
|
if session != 0 {
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
module.Logout(session)
|
_ = module.Logout(session)
|
||||||
}
|
}
|
||||||
module.CloseSession(session)
|
_ = module.CloseSession(session)
|
||||||
}
|
}
|
||||||
module.Finalize()
|
_ = module.Finalize()
|
||||||
module.Destroy()
|
module.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,21 +55,9 @@ var (
|
|||||||
// algorithm isn't supported.
|
// algorithm isn't supported.
|
||||||
ErrUnsupportedHash = errors.New("unsupported hash algorithm")
|
ErrUnsupportedHash = errors.New("unsupported hash algorithm")
|
||||||
|
|
||||||
// Predefined system store names.
|
RolesanywhereSigningName = "rolesanywhere"
|
||||||
// See: https://learn.microsoft.com/en-us/windows/win32/seccrypto/system-store-locations
|
|
||||||
SystemStoreNames = []string{
|
|
||||||
"MY",
|
|
||||||
"Root",
|
|
||||||
"Trust",
|
|
||||||
"CA",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signing name for the IAM Roles Anywhere service
|
|
||||||
ROLESANYWHERE_SIGNING_NAME = "rolesanywhere"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Interface that all signers will have to implement
|
|
||||||
// (as a result, they will also implement crypto.Signer)
|
|
||||||
type Signer interface {
|
type Signer interface {
|
||||||
Public() crypto.PublicKey
|
Public() crypto.PublicKey
|
||||||
Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
|
Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
|
||||||
@@ -78,7 +66,6 @@ type Signer interface {
|
|||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container for certificate data returned to the SDK as JSON.
|
|
||||||
type CertificateData struct {
|
type CertificateData struct {
|
||||||
// Type for the key contained in the certificate.
|
// Type for the key contained in the certificate.
|
||||||
// Passed back to the `sign-string` command
|
// Passed back to the `sign-string` command
|
||||||
@@ -93,7 +80,6 @@ type CertificateData struct {
|
|||||||
Algorithms []string `json:"supportedAlgorithms"`
|
Algorithms []string `json:"supportedAlgorithms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container that adheres to the format of credential_process output as specified by AWS.
|
|
||||||
type CredentialProcessOutput struct {
|
type CredentialProcessOutput struct {
|
||||||
// This field should be hard-coded to 1 for now.
|
// This field should be hard-coded to 1 for now.
|
||||||
Version int `json:"Version"`
|
Version int `json:"Version"`
|
||||||
@@ -118,17 +104,15 @@ type CertificateContainer struct {
|
|||||||
|
|
||||||
// Define constants used in signing
|
// Define constants used in signing
|
||||||
const (
|
const (
|
||||||
aws4_x509_rsa_sha256 = "AWS4-X509-RSA-SHA256"
|
aws4X509RsaSha256 = "AWS4-X509-RSA-SHA256"
|
||||||
aws4_x509_ecdsa_sha256 = "AWS4-X509-ECDSA-SHA256"
|
aws4X509EcdsaSha256 = "AWS4-X509-ECDSA-SHA256"
|
||||||
timeFormat = "20060102T150405Z"
|
timeFormat = "20060102T150405Z"
|
||||||
shortTimeFormat = "20060102"
|
shortTimeFormat = "20060102"
|
||||||
x_amz_date = "X-Amz-Date"
|
xAmzDate = "X-Amz-Date"
|
||||||
x_amz_x509 = "X-Amz-X509"
|
xAmzX509 = "X-Amz-X509"
|
||||||
x_amz_x509_chain = "X-Amz-X509-Chain"
|
xAmzX509Chain = "X-Amz-X509-Chain"
|
||||||
x_amz_content_sha256 = "X-Amz-Content-Sha256"
|
|
||||||
authorization = "Authorization"
|
authorization = "Authorization"
|
||||||
host = "Host"
|
host = "Host"
|
||||||
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Headers that aren't included in calculating the signature
|
// Headers that aren't included in calculating the signature
|
||||||
@@ -138,11 +122,10 @@ var ignoredHeaderKeys = map[string]bool{
|
|||||||
"X-Amzn-Trace-Id": true,
|
"X-Amzn-Trace-Id": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var Debug bool = false
|
var Debug = false
|
||||||
|
|
||||||
// Prompts the user for their password
|
|
||||||
func GetPassword(ttyReadFile *os.File, ttyWriteFile *os.File, prompt string, parseErrMsg string) (string, error) {
|
func GetPassword(ttyReadFile *os.File, ttyWriteFile *os.File, prompt string, parseErrMsg string) (string, error) {
|
||||||
fmt.Fprintln(ttyWriteFile, prompt)
|
_, _ = fmt.Fprintln(ttyWriteFile, prompt)
|
||||||
passwordBytes, err := term.ReadPassword(int(ttyReadFile.Fd()))
|
passwordBytes, err := term.ReadPassword(int(ttyReadFile.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New(parseErrMsg)
|
return "", errors.New(parseErrMsg)
|
||||||
@@ -220,13 +203,17 @@ func PasswordPrompt(passwordPromptInput PasswordPromptProps) (string, interface{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errors.New(parseErrMsg)
|
return "", nil, errors.New(parseErrMsg)
|
||||||
}
|
}
|
||||||
defer ttyReadFile.Close()
|
defer func(ttyReadFile *os.File) {
|
||||||
|
_ = ttyReadFile.Close()
|
||||||
|
}(ttyReadFile)
|
||||||
|
|
||||||
ttyWriteFile, err = os.OpenFile(ttyWritePath, os.O_WRONLY, 0)
|
ttyWriteFile, err = os.OpenFile(ttyWritePath, os.O_WRONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errors.New(parseErrMsg)
|
return "", nil, errors.New(parseErrMsg)
|
||||||
}
|
}
|
||||||
defer ttyWriteFile.Close()
|
defer func(ttyWriteFile *os.File) {
|
||||||
|
_ = ttyWriteFile.Close()
|
||||||
|
}(ttyWriteFile)
|
||||||
|
|
||||||
// The key has a password, so prompt for it
|
// The key has a password, so prompt for it
|
||||||
password, err = GetPassword(ttyReadFile, ttyWriteFile, prompt, parseErrMsg)
|
password, err = GetPassword(ttyReadFile, ttyWriteFile, prompt, parseErrMsg)
|
||||||
@@ -234,7 +221,7 @@ func PasswordPrompt(passwordPromptInput PasswordPromptProps) (string, interface{
|
|||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
checkPasswordResult, err = checkPassword(password)
|
checkPasswordResult, err = checkPassword(password)
|
||||||
for true {
|
for {
|
||||||
// If we've found the right password, return both it and the result of `checkPassword`
|
// If we've found the right password, return both it and the result of `checkPassword`
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return password, checkPasswordResult, nil
|
return password, checkPasswordResult, nil
|
||||||
@@ -250,11 +237,8 @@ func PasswordPrompt(passwordPromptInput PasswordPromptProps) (string, interface{
|
|||||||
}
|
}
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default function to showcase certificate information
|
|
||||||
func DefaultCertContainerToString(certContainer CertificateContainer) string {
|
func DefaultCertContainerToString(certContainer CertificateContainer) string {
|
||||||
var certStr string
|
var certStr string
|
||||||
|
|
||||||
@@ -272,7 +256,6 @@ func DefaultCertContainerToString(certContainer CertificateContainer) string {
|
|||||||
return certStr
|
return certStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertificateContainerList implements the sort.Interface interface
|
|
||||||
type CertificateContainerList []CertificateContainer
|
type CertificateContainerList []CertificateContainer
|
||||||
|
|
||||||
func (certificateContainerList CertificateContainerList) Less(i, j int) bool {
|
func (certificateContainerList CertificateContainerList) Less(i, j int) bool {
|
||||||
@@ -312,7 +295,7 @@ func certMatches(certIdentifier CertIdentifier, cert x509.Certificate) bool {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// This is defined in RFC3279 §2.2.3 as well as SEC.1.
|
// This is defined in RFC3279 §2.2.3 as well as SEC.1.
|
||||||
// I can't find anything which mandates DER but I've seen
|
// I can't find anything which mandates DER, but I've seen
|
||||||
// OpenSSL refusing to verify it with indeterminate length.
|
// OpenSSL refusing to verify it with indeterminate length.
|
||||||
func encodeEcdsaSigValue(signature []byte) (out []byte, err error) {
|
func encodeEcdsaSigValue(signature []byte) (out []byte, err error) {
|
||||||
sigLen := len(signature) / 2
|
sigLen := len(signature) / 2
|
||||||
@@ -335,9 +318,6 @@ func GetSigner(opts *CredentialsOpts) (signer Signer, signatureAlgorithm string,
|
|||||||
privateKeyId := opts.PrivateKeyId
|
privateKeyId := opts.PrivateKeyId
|
||||||
if privateKeyId == "" {
|
if privateKeyId == "" {
|
||||||
if opts.CertificateId == "" {
|
if opts.CertificateId == "" {
|
||||||
if Debug {
|
|
||||||
log.Println("attempting to use CertStoreSigner")
|
|
||||||
}
|
|
||||||
return GetCertStoreSigner(opts.CertIdentifier, opts.UseLatestExpiringCertificate)
|
return GetCertStoreSigner(opts.CertIdentifier, opts.UseLatestExpiringCertificate)
|
||||||
}
|
}
|
||||||
privateKeyId = opts.CertificateId
|
privateKeyId = opts.CertificateId
|
||||||
@@ -348,9 +328,7 @@ func GetSigner(opts *CredentialsOpts) (signer Signer, signatureAlgorithm string,
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
certificate = cert
|
certificate = cert
|
||||||
} else if opts.PrivateKeyId == "" {
|
} else if opts.PrivateKeyId == "" {
|
||||||
if Debug {
|
|
||||||
log.Println("not a PEM certificate, so trying PKCS#12")
|
|
||||||
}
|
|
||||||
if opts.CertificateBundleId != "" {
|
if opts.CertificateBundleId != "" {
|
||||||
return nil, "", errors.New("can't specify certificate chain when" +
|
return nil, "", errors.New("can't specify certificate chain when" +
|
||||||
" using PKCS#12 files; certificate bundle should be provided" +
|
" using PKCS#12 files; certificate bundle should be provided" +
|
||||||
@@ -375,17 +353,11 @@ func GetSigner(opts *CredentialsOpts) (signer Signer, signatureAlgorithm string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(privateKeyId, "pkcs11:") {
|
if strings.HasPrefix(privateKeyId, "pkcs11:") {
|
||||||
if Debug {
|
|
||||||
log.Println("attempting to use PKCS11Signer")
|
|
||||||
}
|
|
||||||
if certificate != nil {
|
if certificate != nil {
|
||||||
opts.CertificateId = ""
|
opts.CertificateId = ""
|
||||||
}
|
}
|
||||||
return GetPKCS11Signer(opts.LibPkcs11, certificate, certificateChain, opts.PrivateKeyId, opts.CertificateId, opts.ReusePin)
|
return GetPKCS11Signer(opts.LibPkcs11, certificate, certificateChain, opts.PrivateKeyId, opts.CertificateId, opts.ReusePin)
|
||||||
} else if strings.HasPrefix(privateKeyId, "handle:") {
|
} else if strings.HasPrefix(privateKeyId, "handle:") {
|
||||||
if Debug {
|
|
||||||
log.Println("attempting to use TPMv2Signer")
|
|
||||||
}
|
|
||||||
return GetTPMv2Signer(
|
return GetTPMv2Signer(
|
||||||
GetTPMv2SignerOpts{
|
GetTPMv2SignerOpts{
|
||||||
certificate,
|
certificate,
|
||||||
@@ -399,9 +371,6 @@ func GetSigner(opts *CredentialsOpts) (signer Signer, signatureAlgorithm string,
|
|||||||
} else {
|
} else {
|
||||||
tpmKey, err := parseDERFromPEM(privateKeyId, "TSS2 PRIVATE KEY")
|
tpmKey, err := parseDERFromPEM(privateKeyId, "TSS2 PRIVATE KEY")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if Debug {
|
|
||||||
log.Println("attempting to use TPMv2Signer")
|
|
||||||
}
|
|
||||||
return GetTPMv2Signer(
|
return GetTPMv2Signer(
|
||||||
GetTPMv2SignerOpts{
|
GetTPMv2SignerOpts{
|
||||||
certificate,
|
certificate,
|
||||||
@@ -424,24 +393,18 @@ func GetSigner(opts *CredentialsOpts) (signer Signer, signatureAlgorithm string,
|
|||||||
if certificate == nil {
|
if certificate == nil {
|
||||||
return nil, "", errors.New("undefined certificate value")
|
return nil, "", errors.New("undefined certificate value")
|
||||||
}
|
}
|
||||||
if Debug {
|
|
||||||
log.Println("attempting to use FileSystemSigner")
|
|
||||||
}
|
|
||||||
return GetFileSystemSigner(privateKeyId, opts.CertificateId, opts.CertificateBundleId, false, opts.Pkcs8Password)
|
return GetFileSystemSigner(privateKeyId, opts.CertificateId, opts.CertificateBundleId, false, opts.Pkcs8Password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the date-time, formatted as specified by SigV4
|
|
||||||
func (signerParams *SignerParams) GetFormattedSigningDateTime() string {
|
func (signerParams *SignerParams) GetFormattedSigningDateTime() string {
|
||||||
return signerParams.OverriddenDate.UTC().Format(timeFormat)
|
return signerParams.OverriddenDate.UTC().Format(timeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the short date-time, formatted as specified by SigV4
|
|
||||||
func (signerParams *SignerParams) GetFormattedShortSigningDateTime() string {
|
func (signerParams *SignerParams) GetFormattedShortSigningDateTime() string {
|
||||||
return signerParams.OverriddenDate.UTC().Format(shortTimeFormat)
|
return signerParams.OverriddenDate.UTC().Format(shortTimeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the scope as part of the SigV4-X509 signature
|
|
||||||
func (signerParams *SignerParams) GetScope() string {
|
func (signerParams *SignerParams) GetScope() string {
|
||||||
var scopeStringBuilder strings.Builder
|
var scopeStringBuilder strings.Builder
|
||||||
scopeStringBuilder.WriteString(signerParams.GetFormattedShortSigningDateTime())
|
scopeStringBuilder.WriteString(signerParams.GetFormattedShortSigningDateTime())
|
||||||
@@ -486,14 +449,14 @@ func CreateRequestSignFinalizeFunction(signer crypto.Signer, signingRegion strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func signRequest(signer crypto.Signer, signingRegion string, signingAlgorithm string, certificate *x509.Certificate, certificateChain []*x509.Certificate, req *http.Request, payloadHash string) {
|
func signRequest(signer crypto.Signer, signingRegion string, signingAlgorithm string, certificate *x509.Certificate, certificateChain []*x509.Certificate, req *http.Request, payloadHash string) {
|
||||||
signerParams := SignerParams{time.Now(), signingRegion, ROLESANYWHERE_SIGNING_NAME, signingAlgorithm}
|
signerParams := SignerParams{time.Now(), signingRegion, RolesanywhereSigningName, signingAlgorithm}
|
||||||
|
|
||||||
// Set headers that are necessary for signing
|
// Set headers that are necessary for signing
|
||||||
req.Header.Set(host, req.URL.Host)
|
req.Header.Set(host, req.URL.Host)
|
||||||
req.Header.Set(x_amz_date, signerParams.GetFormattedSigningDateTime())
|
req.Header.Set(xAmzDate, signerParams.GetFormattedSigningDateTime())
|
||||||
req.Header.Set(x_amz_x509, certificateToString(certificate))
|
req.Header.Set(xAmzX509, certificateToString(certificate))
|
||||||
if certificateChain != nil {
|
if certificateChain != nil {
|
||||||
req.Header.Set(x_amz_x509_chain, certificateChainToString(certificateChain))
|
req.Header.Set(xAmzX509Chain, certificateChainToString(certificateChain))
|
||||||
}
|
}
|
||||||
|
|
||||||
canonicalRequest, signedHeadersString := createCanonicalRequest(req, payloadHash)
|
canonicalRequest, signedHeadersString := createCanonicalRequest(req, payloadHash)
|
||||||
@@ -609,7 +572,6 @@ func createCanonicalRequest(r *http.Request, contentSha256 string) (string, stri
|
|||||||
return hex.EncodeToString(canonicalRequestStringHashBytes[:]), signedHeadersString
|
return hex.EncodeToString(canonicalRequestStringHashBytes[:]), signedHeadersString
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the string to sign.
|
|
||||||
func CreateStringToSign(canonicalRequest string, signerParams SignerParams) string {
|
func CreateStringToSign(canonicalRequest string, signerParams SignerParams) string {
|
||||||
var stringToSignStrBuilder strings.Builder
|
var stringToSignStrBuilder strings.Builder
|
||||||
stringToSignStrBuilder.WriteString(signerParams.SigningAlgorithm)
|
stringToSignStrBuilder.WriteString(signerParams.SigningAlgorithm)
|
||||||
@@ -623,8 +585,7 @@ func CreateStringToSign(canonicalRequest string, signerParams SignerParams) stri
|
|||||||
return stringToSign
|
return stringToSign
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builds the complete authorization header
|
func BuildAuthorizationHeader(_ *http.Request, signedHeadersString string, signature string, certificate *x509.Certificate, signerParams SignerParams) string {
|
||||||
func BuildAuthorizationHeader(request *http.Request, signedHeadersString string, signature string, certificate *x509.Certificate, signerParams SignerParams) string {
|
|
||||||
signingCredentials := certificate.SerialNumber.String() + "/" + signerParams.GetScope()
|
signingCredentials := certificate.SerialNumber.String() + "/" + signerParams.GetScope()
|
||||||
credential := "Credential=" + signingCredentials
|
credential := "Credential=" + signingCredentials
|
||||||
signerHeaders := "SignedHeaders=" + signedHeadersString
|
signerHeaders := "SignedHeaders=" + signedHeadersString
|
||||||
@@ -645,20 +606,20 @@ func BuildAuthorizationHeader(request *http.Request, signedHeadersString string,
|
|||||||
func encodeDer(der []byte) (string, error) {
|
func encodeDer(der []byte) (string, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
encoder := base64.NewEncoder(base64.StdEncoding, &buf)
|
encoder := base64.NewEncoder(base64.StdEncoding, &buf)
|
||||||
encoder.Write(der)
|
_, _ = encoder.Write(der)
|
||||||
encoder.Close()
|
_ = encoder.Close()
|
||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDERFromPEM(pemDataId string, blockType string) (*pem.Block, error) {
|
func parseDERFromPEM(pemDataId string, blockType string) (*pem.Block, error) {
|
||||||
bytes, err := os.ReadFile(pemDataId)
|
bts, err := os.ReadFile(pemDataId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var block *pem.Block
|
var block *pem.Block
|
||||||
for len(bytes) > 0 {
|
for len(bts) > 0 {
|
||||||
block, bytes = pem.Decode(bytes)
|
block, bts = pem.Decode(bts)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil, errors.New("unable to parse PEM data")
|
return nil, errors.New("unable to parse PEM data")
|
||||||
}
|
}
|
||||||
@@ -669,17 +630,16 @@ func parseDERFromPEM(pemDataId string, blockType string) (*pem.Block, error) {
|
|||||||
return nil, errors.New("requested block type could not be found")
|
return nil, errors.New("requested block type could not be found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads certificate bundle data from a file, whose path is provided
|
|
||||||
func ReadCertificateBundleData(certificateBundleId string) ([]*x509.Certificate, error) {
|
func ReadCertificateBundleData(certificateBundleId string) ([]*x509.Certificate, error) {
|
||||||
bytes, err := os.ReadFile(certificateBundleId)
|
bts, err := os.ReadFile(certificateBundleId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var derBytes []byte
|
var derBytes []byte
|
||||||
var block *pem.Block
|
var block *pem.Block
|
||||||
for len(bytes) > 0 {
|
for len(bts) > 0 {
|
||||||
block, bytes = pem.Decode(bytes)
|
block, bts = pem.Decode(bts)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -721,30 +681,21 @@ func readRSAPrivateKey(privateKeyId string) (*rsa.PrivateKey, error) {
|
|||||||
return privateKey, nil
|
return privateKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads and parses a PKCS#12 file (which should contain an end-entity
|
|
||||||
// certificate (optional), certificate chain (optional), and the key
|
|
||||||
// associated with the end-entity certificate). The end-entity certificate
|
|
||||||
// will be the first certificate in the returned chain. This method assumes
|
|
||||||
// that there is exactly one certificate that doesn't issue any others within
|
|
||||||
// the container and treats that as the end-entity certificate. Also, the
|
|
||||||
// order of the other certificates in the chain aren't guaranteed. It's
|
|
||||||
// also not guaranteed that those certificates form a chain with the
|
|
||||||
// end-entity certificate either.
|
|
||||||
func ReadPKCS12Data(certificateId string) (certChain []*x509.Certificate, privateKey crypto.PrivateKey, err error) {
|
func ReadPKCS12Data(certificateId string) (certChain []*x509.Certificate, privateKey crypto.PrivateKey, err error) {
|
||||||
var (
|
var (
|
||||||
bytes []byte
|
bts []byte
|
||||||
pemBlocks []*pem.Block
|
pemBlocks []*pem.Block
|
||||||
parsedCerts []*x509.Certificate
|
parsedCerts []*x509.Certificate
|
||||||
certMap map[string]*x509.Certificate
|
certMap map[string]*x509.Certificate
|
||||||
endEntityFoundIndex int
|
endEntityFoundIndex int
|
||||||
)
|
)
|
||||||
|
|
||||||
bytes, err = os.ReadFile(certificateId)
|
bts, err = os.ReadFile(certificateId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pemBlocks, err = pkcs12.ToPEM(bytes, "")
|
pemBlocks, err = pkcs12.ToPEM(bts, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
@@ -760,11 +711,6 @@ func ReadPKCS12Data(certificateId string) (certChain []*x509.Certificate, privat
|
|||||||
privateKey = privateKeyTmp
|
privateKey = privateKeyTmp
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// If neither a certificate nor a private key could be parsed from the
|
|
||||||
// Block, ignore it and continue.
|
|
||||||
if Debug {
|
|
||||||
log.Println("unable to parse PEM block in PKCS#12 file - skipping")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
certMap = make(map[string]*x509.Certificate)
|
certMap = make(map[string]*x509.Certificate)
|
||||||
@@ -784,10 +730,6 @@ func ReadPKCS12Data(certificateId string) (certChain []*x509.Certificate, privat
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if Debug {
|
|
||||||
log.Println("no end-entity certificate found in PKCS#12 file")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, cert := range parsedCerts {
|
for i, cert := range parsedCerts {
|
||||||
if i != endEntityFoundIndex {
|
if i != endEntityFoundIndex {
|
||||||
certChain = append(certChain, cert)
|
certChain = append(certChain, cert)
|
||||||
@@ -797,7 +739,6 @@ func ReadPKCS12Data(certificateId string) (certChain []*x509.Certificate, privat
|
|||||||
return certChain, privateKey, nil
|
return certChain, privateKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the private key referenced by `privateKeyId`. If `pkcs8Password` is provided, attempt to load an encrypted PKCS#8 key.
|
|
||||||
func ReadPrivateKeyData(privateKeyId string, pkcs8Password ...string) (crypto.PrivateKey, error) {
|
func ReadPrivateKeyData(privateKeyId string, pkcs8Password ...string) (crypto.PrivateKey, error) {
|
||||||
if len(pkcs8Password) > 0 && pkcs8Password[0] != "" {
|
if len(pkcs8Password) > 0 && pkcs8Password[0] != "" {
|
||||||
if key, err := readPKCS8EncryptedPrivateKey(privateKeyId, []byte(pkcs8Password[0])); err == nil {
|
if key, err := readPKCS8EncryptedPrivateKey(privateKeyId, []byte(pkcs8Password[0])); err == nil {
|
||||||
@@ -822,7 +763,6 @@ func ReadPrivateKeyData(privateKeyId string, pkcs8Password ...string) (crypto.Pr
|
|||||||
return nil, errors.New("unable to parse private key")
|
return nil, errors.New("unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads private key data from a *pem.Block.
|
|
||||||
func ReadPrivateKeyDataFromPEMBlock(block *pem.Block) (key crypto.PrivateKey, err error) {
|
func ReadPrivateKeyDataFromPEMBlock(block *pem.Block) (key crypto.PrivateKey, err error) {
|
||||||
key, err = x509.ParseECPrivateKey(block.Bytes)
|
key, err = x509.ParseECPrivateKey(block.Bytes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -423,9 +423,9 @@ func GetTPMv2Signer(opts GetTPMv2SignerOpts) (signer Signer, signingAlgorithm st
|
|||||||
|
|
||||||
switch public.Type {
|
switch public.Type {
|
||||||
case tpm2.AlgRSA:
|
case tpm2.AlgRSA:
|
||||||
signingAlgorithm = aws4_x509_rsa_sha256
|
signingAlgorithm = aws4X509RsaSha256
|
||||||
case tpm2.AlgECC:
|
case tpm2.AlgECC:
|
||||||
signingAlgorithm = aws4_x509_ecdsa_sha256
|
signingAlgorithm = aws4X509EcdsaSha256
|
||||||
default:
|
default:
|
||||||
return nil, "", errors.New("unsupported TPMv2 key type")
|
return nil, "", errors.New("unsupported TPMv2 key type")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user