in aws_signing_helper/pkcs11_signer.go [1198:1328]
func GetPKCS11Signer(libPkcs11 string, cert *x509.Certificate, certChain []*x509.Certificate, privateKeyId string, certificateId string, reusePin bool) (signer Signer, signingAlgorithm string, err error) {
var (
module *pkcs11.Ctx
certObj CertObjInfo
session pkcs11.SessionHandle
loggedIn bool
keyType uint
contextSpecificPin string
userPin string
alwaysAuth uint
certSlotNr uint
certUri *pkcs11uri.Pkcs11URI
keyUri *pkcs11uri.Pkcs11URI
slots []SlotIdInfo
certSlot SlotIdInfo
noKeyUri bool
)
module, err = initializePKCS11Module(libPkcs11)
if err != nil {
goto fail
}
// If a PKCS#11 URI was provided for the certificate, find it.
if cert == nil && certificateId != "" {
certUri = pkcs11uri.New()
err = certUri.Parse(certificateId)
if err != nil {
goto fail
}
userPin, _ = certUri.GetQueryAttribute("pin-value", false)
certSlot, slots, session, loggedIn, certObj, err = getCertificate(module, certUri, userPin)
if err != nil {
goto fail
}
certSlotNr = certSlot.id
cert = certObj.cert
// So that hunting for the certificate can be more efficient in the future,
// update the cert URI that has CKA_ID and CKA_VALUE appropriately set.
crtAttributes := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_ID, 0),
}
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
if err == nil {
certUri.SetPathAttribute("id", escapeAll(crtAttributes[0].Value))
}
crtAttributes = []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_LABEL, 0),
}
crtAttributes, err = module.GetAttributeValue(session, certObj.certObject, crtAttributes)
if err == nil {
certUri.SetPathAttribute("object", escapeAll(crtAttributes[0].Value))
}
if certChain == nil {
certChain, err = getCertificateChain(module, session, cert)
if err != nil {
goto fail
}
}
} else if cert != nil {
// Populate certObj, so that it can be used to find the matching private key.
certObj = CertObjInfo{nil, nil, cert, 0}
}
// If an explicit private-key option was given, use it. Otherwise
// we look in the same place as the certificate URI as directed by
// http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#rfc.section.8.2
if privateKeyId != "" {
keyUri = pkcs11uri.New()
err = keyUri.Parse(privateKeyId)
if err != nil {
goto fail
}
} else {
certUriStr, _ := certUri.Format()
keyUri = pkcs11uri.New()
keyUri.Parse(certUriStr)
noKeyUri = true
}
if _userPin, ok := keyUri.GetQueryAttribute("pin-value", false); ok {
userPin = _userPin
}
// If the certificate's PKCS#11 URI wasn't provided, enumerate slots.
if certificateId == "" {
slots, err = enumerateSlotsInPKCS11Module(module)
if err != nil {
goto fail
}
}
session, userPin, keyUri, keyType, _, _, alwaysAuth, contextSpecificPin, err = getPKCS11Key(module, session, loggedIn, certUri, keyUri, noKeyUri, certSlotNr, certObj, userPin, "", reusePin, slots)
if err != nil {
goto fail
}
switch keyType {
case pkcs11.CKK_EC:
signingAlgorithm = aws4_x509_ecdsa_sha256
case pkcs11.CKK_RSA:
signingAlgorithm = aws4_x509_rsa_sha256
default:
return nil, "", errors.New("unsupported algorithm")
}
if session != 0 {
if loggedIn {
module.Logout(session)
}
module.CloseSession(session)
}
return &PKCS11Signer{cert, certChain, module, userPin, alwaysAuth, contextSpecificPin, certUri, keyUri, reusePin}, signingAlgorithm, nil
fail:
if module != nil {
if session != 0 {
if loggedIn {
module.Logout(session)
}
module.CloseSession(session)
}
module.Finalize()
module.Destroy()
}
return nil, "", err
}