// Sign performs a signature using the PKCS #11 key. func (ps *PKCS11Key) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) { // Verify that the length of the hash is as expected hash := opts.HashFunc() hashLen := hash.Size() if len(msg) != hashLen { err = errors.New("input size does not match hash function output size") return } // Add DigestInfo prefix // TODO: Switch mechanisms based on CKA_KEY_TYPE mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} prefix, ok := hashPrefixes[hash] if !ok { err = errors.New("unknown hash function") return } signatureInput := append(prefix, msg...) // Open a session session, err := ps.openSession() if err != nil { return } defer ps.closeSession(session) // Perform the sign operation err = ps.module.SignInit(session, mechanism, ps.privateKeyHandle) if err != nil { return } signature, err = ps.module.Sign(session, signatureInput) return }
// Sign returns a signature for a given signature request func sign(ctx IPKCS11Ctx, session pkcs11.SessionHandle, pkcs11KeyID []byte, passRetriever passphrase.Retriever, payload []byte) ([]byte, error) { err := login(ctx, session, passRetriever, pkcs11.CKU_USER, USER_PIN) if err != nil { return nil, fmt.Errorf("error logging in: %v", err) } defer ctx.Logout(session) // Define the ECDSA Private key template class := pkcs11.CKO_PRIVATE_KEY privateKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_CLASS, class), pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA), pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID), } if err := ctx.FindObjectsInit(session, privateKeyTemplate); err != nil { logrus.Debugf("Failed to init find objects: %s", err.Error()) return nil, err } obj, _, err := ctx.FindObjects(session, 1) if err != nil { logrus.Debugf("Failed to find objects: %v", err) return nil, err } if err = ctx.FindObjectsFinal(session); err != nil { logrus.Debugf("Failed to finalize find objects: %s", err.Error()) return nil, err } if len(obj) != 1 { return nil, errors.New("length of objects found not 1") } var sig []byte err = ctx.SignInit( session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)}, obj[0]) if err != nil { return nil, err } // Get the SHA256 of the payload digest := sha256.Sum256(payload) if (yubikeyKeymode & KeymodeTouch) > 0 { touchToSignUI() defer touchDoneCallback() } // a call to Sign, whether or not Sign fails, will clear the SignInit sig, err = ctx.Sign(session, digest[:]) if err != nil { logrus.Debugf("Error while signing: %s", err) return nil, err } if sig == nil { return nil, errors.New("Failed to create signature") } return sig[:], nil }
// Sign performs a signature using the PKCS #11 key. func (ps *Key) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) { ps.sessionMu.Lock() defer ps.sessionMu.Unlock() if ps.session == nil { return nil, errors.New("Session was nil") } // When the alwaysAuthenticate bit is true (e.g. on a Yubikey NEO in PIV mode), // each Sign has to include a Logout/Login, or the next Sign request will get // CKR_USER_NOT_LOGGED_IN. This is very slow, but on the NEO it's not possible // to clear the CKA_ALWAYS_AUTHENTICATE bit, so this is the only available // workaround. // Also, since logged in / logged out is application state rather than session // state, we take a global lock while we do the logout and login, and during // the signing. if ps.alwaysAuthenticate { modulesMu.Lock() defer modulesMu.Unlock() if err := ps.module.Logout(*ps.session); err != nil { return nil, fmt.Errorf("logout: %s", err) } if err = ps.module.Login(*ps.session, pkcs11.CKU_USER, ps.pin); err != nil { return nil, fmt.Errorf("login: %s", err) } } // Verify that the length of the hash is as expected hash := opts.HashFunc() hashLen := hash.Size() if len(msg) != hashLen { err = errors.New("input size does not match hash function output size") return } // Add DigestInfo prefix // TODO: Switch mechanisms based on CKA_KEY_TYPE mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} prefix, ok := hashPrefixes[hash] if !ok { err = errors.New("unknown hash function") return } signatureInput := append(prefix, msg...) // Perform the sign operation err = ps.module.SignInit(*ps.session, mechanism, ps.privateKeyHandle) if err != nil { return nil, fmt.Errorf("sign init: %s", err) } signature, err = ps.module.Sign(*ps.session, signatureInput) if err != nil { return nil, fmt.Errorf("sign: %s", err) } return }
// Sign returns a signature for a given signature request func (s *RSAHardwareCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) { signatures := make([]data.Signature, 0, len(keyIDs)) for _, keyid := range keyIDs { privateKey, present := s.keys[keyid] if !present { // We skip keys that aren't found continue } priv := privateKey.PKCS11ObjectHandle() var sig []byte var err error for i := 0; i < 3; i++ { s.context.SignInit(s.session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA256_RSA_PKCS, nil)}, priv) sig, err = s.context.Sign(s.session, payload) if err != nil { log.Printf("Error while signing: %s", err) continue } digest := sha256.Sum256(payload) pub, err := x509.ParsePKIXPublicKey(privateKey.Public()) if err != nil { log.Printf("Failed to parse public key: %s\n", err) return nil, err } rsaPub, ok := pub.(*rsa.PublicKey) if !ok { log.Printf("Value returned from ParsePKIXPublicKey was not an RSA public key") return nil, err } err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, digest[:], sig) if err != nil { log.Printf("Failed verification. Retrying: %s", err) continue } break } if sig == nil { return nil, errors.New("Failed to create signature") } signatures = append(signatures, data.Signature{ KeyID: keyid, Method: data.RSAPKCS1v15Signature, Signature: sig[:], }) } return signatures, nil }
func (s *signer) sign(input []byte) ([]byte, error) { mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} if err := s.context.SignInit(s.session, mechanism, s.privateKey); err != nil { log.Fatalf("SignInit: %s", err) } signed, err := s.context.Sign(s.session, input) if err != nil { log.Fatalf("Sign: %s", err) } return signed, nil }
// Sign returns a signature for a given signature request func (s *RSASigner) Sign(request *pb.SignatureRequest) (*pb.Signature, error) { priv := s.privateKey.PKCS11ObjectHandle() var sig []byte var err error for i := 0; i < 3; i++ { //TODO(mccauley): move this to RSA OAEP s.context.SignInit(s.session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA256_RSA_PKCS, nil)}, priv) sig, err = s.context.Sign(s.session, request.Content) if err != nil { log.Printf("Error while signing: %s", err) continue } // (diogo): XXX: Remove this before shipping digest := sha256.Sum256(request.Content) pub, err := x509.ParsePKIXPublicKey(s.privateKey.Public()) if err != nil { log.Printf("Failed to parse public key: %s\n", err) return nil, err } rsaPub, ok := pub.(*rsa.PublicKey) if !ok { log.Printf("Value returned from ParsePKIXPublicKey was not an RSA public key") return nil, err } err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, digest[:], sig) if err != nil { log.Printf("Failed verification. Retrying: %s", err) continue } break } // (diogo): XXX: END Area of removal if sig == nil { return nil, errors.New("Failed to create signature") } returnSig := &pb.Signature{KeyInfo: &pb.KeyInfo{KeyID: &pb.KeyID{ID: s.privateKey.ID()}, Algorithm: &pb.Algorithm{Algorithm: s.privateKey.Algorithm().String()}}, Content: sig[:]} log.Printf("[Notary-signer Server] Signature request JSON: %s , response: %s", string(request.Content), returnSig) return returnSig, nil }
// Create creates a key and returns its public components func (s *RSAHardwareCryptoService) Create(role, algo string) (data.PublicKey, error) { // For now generate random labels for keys // (diogo): add link between keyID and label in database so we can support multiple keys randomLabel := make([]byte, 32) _, err := rand.Read(randomLabel) if err != nil { return nil, errors.New("Could not generate a random key label.") } // Set the public key template // CKA_TOKEN: Guarantees key persistence in hardware // CKA_LABEL: Identifies this specific key inside of the HSM publicKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{3}), pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, 2048), pkcs11.NewAttribute(pkcs11.CKA_LABEL, string(randomLabel)), } privateKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true), pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), pkcs11.NewAttribute(pkcs11.CKA_LABEL, string(randomLabel)), } // Generate a new RSA private/public keypair inside of the HSM pub, priv, err := s.context.GenerateKeyPair(s.session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, publicKeyTemplate, privateKeyTemplate) if err != nil { return nil, errors.New("Could not generate a new key inside of the HSM.") } // (diogo): This template is used for the GetAttribute template := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil), pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, nil), pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil), } // Retrieve the public-key material to be able to create a new HSMRSAKey attr, err := s.context.GetAttributeValue(s.session, pub, template) if err != nil { return nil, errors.New("Failed to get Attribute value.") } // We're going to store the elements of the RSA Public key, exponent and Modulus inside of exp and mod var exp int mod := big.NewInt(0) // Iterate through all the attributes of this key and saves CKA_PUBLIC_EXPONENT and CKA_MODULUS. Removes ordering specific issues. for _, a := range attr { if a.Type == pkcs11.CKA_PUBLIC_EXPONENT { exp, _ = readInt(a.Value) } if a.Type == pkcs11.CKA_MODULUS { mod.SetBytes(a.Value) } } rsaPublicKey := rsa.PublicKey{N: mod, E: exp} // Using x509 to Marshal the Public key into der encoding pubBytes, err := x509.MarshalPKIXPublicKey(&rsaPublicKey) if err != nil { return nil, errors.New("Failed to Marshal public key.") } // (diogo): Ideally I would like to return base64 PEM encoded public keys to the client k := keys.NewHSMRSAKey(pubBytes, priv) keyID := k.ID() s.keys[keyID] = k return k, nil }
func generate_pkcs11keypair() { config := configure() p := pkcs11.New(config.module) if p == nil { fmt.Printf("Could not initialize pkcs11 with module %s, exiting.\n", config.module) os.Exit(1) } p.Initialize() defer p.Destroy() defer p.Finalize() var used_slot uint = 0 slots, _ := p.GetSlotList(true) for _, slot_id := range slots { if slot_id == config.slot_id { used_slot = config.slot_id } } fmt.Printf("Wanted slot id %v ", config.slot_id) fmt.Printf("and got slot id %v.\n", used_slot) session, err := p.OpenSession(used_slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) if err != nil { fmt.Printf("Could not open session. Error: %v\n", err) os.Exit(1) } defer p.CloseSession(session) p.Login(session, pkcs11.CKU_USER, config.user_pin) defer p.Logout(session) info, err := p.GetInfo() if err != nil { fmt.Printf("GetInfo failed: %v\n", err) os.Exit(1) } else { fmt.Printf("HSM Info:\nManufacturer ID %v\nFlags: %v\nLibrary Description: %v\nLibrary Version: %v.\n", info.ManufacturerID, info.Flags, info.LibraryDescription, info.LibraryVersion) } // var pub_exponent int = 0x010001 publicKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKO_PUBLIC_KEY), pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, config.rsa_size), pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{3}), pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true), pkcs11.NewAttribute(pkcs11.CKA_WRAP, true), pkcs11.NewAttribute(pkcs11.CKA_LABEL, config.key_label), pkcs11.NewAttribute(pkcs11.CKA_ID, config.key_id), pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, "/CN=Harald Wagener"), } privateKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKO_PRIVATE_KEY), pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true), pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true), pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true), pkcs11.NewAttribute(pkcs11.CKA_LABEL, config.key_label), pkcs11.NewAttribute(pkcs11.CKA_ID, config.key_id), pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, "/CN=Harald Wagener"), } pub, priv, err := p.GenerateKeyPair(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, publicKeyTemplate, privateKeyTemplate) if err != nil { fmt.Printf("Error generating key pair: %v\n", err) os.Exit(1) } else { fmt.Printf("Key pair generated:\nPublic Key: %v\nPrivate Key: %v\n", pub, priv) os.Exit(0) } }