...

Source file src/github.com/sassoftware/relic/token/p11token/ecdsa.go

Documentation: github.com/sassoftware/relic/token/p11token

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package p11token
    18  
    19  import (
    20  	"crypto"
    21  	"crypto/ecdsa"
    22  	"errors"
    23  
    24  	"github.com/miekg/pkcs11"
    25  	"github.com/sassoftware/relic/lib/x509tools"
    26  )
    27  
    28  // Convert token ECDSA public key to *ecdsa.PublicKey
    29  func (key *Key) toEcdsaKey() (crypto.PublicKey, error) {
    30  	ecparams := key.token.getAttribute(key.pub, pkcs11.CKA_EC_PARAMS)
    31  	ecpoint := key.token.getAttribute(key.pub, pkcs11.CKA_EC_POINT)
    32  	if len(ecparams) == 0 || len(ecpoint) == 0 {
    33  		return nil, errors.New("Unable to retrieve ECDSA public key")
    34  	}
    35  	curve, err := x509tools.CurveByDer(ecparams)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	x, y := x509tools.DerToPoint(curve.Curve, ecpoint)
    40  	if x == nil || y == nil {
    41  		return nil, errors.New("Invalid elliptic curve point")
    42  	}
    43  	eckey := &ecdsa.PublicKey{Curve: curve.Curve, X: x, Y: y}
    44  	return eckey, nil
    45  }
    46  
    47  // Sign a digest using token ECDSA private key
    48  func (key *Key) signECDSA(digest []byte) (der []byte, err error) {
    49  	mech := pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)
    50  	err = key.token.ctx.SignInit(key.token.sh, []*pkcs11.Mechanism{mech}, key.priv)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	sig, err := key.token.ctx.Sign(key.token.sh, digest)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	parsed, err := x509tools.UnpackEcdsaSignature(sig)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	return parsed.Marshal(), nil
    63  }
    64  
    65  // Generate ECDSA-specific public and private key attributes from a PrivateKey
    66  func ecdsaImportAttrs(priv *ecdsa.PrivateKey) (pubAttrs, privAttrs []*pkcs11.Attribute, err error) {
    67  	curve, err := x509tools.CurveByCurve(priv.Curve)
    68  	if err != nil {
    69  		return nil, nil, err
    70  	}
    71  	pubAttrs = []*pkcs11.Attribute{
    72  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, curve.ToDer()),
    73  		pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, x509tools.PointToDer(&priv.PublicKey)),
    74  	}
    75  	privAttrs = []*pkcs11.Attribute{
    76  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, curve.ToDer()),
    77  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, priv.D.Bytes()),
    78  	}
    79  	return
    80  }
    81  
    82  // Generate ECDSA-specific public attributes to generate an ECSDA key in the token
    83  func ecdsaGenerateAttrs(bits uint) ([]*pkcs11.Attribute, *pkcs11.Mechanism, error) {
    84  	curve, err := x509tools.CurveByBits(bits)
    85  	if err != nil {
    86  		return nil, nil, err
    87  	}
    88  	pubAttrs := []*pkcs11.Attribute{pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, curve.ToDer())}
    89  	mech := pkcs11.NewMechanism(pkcs11.CKM_EC_KEY_PAIR_GEN, nil)
    90  	return pubAttrs, mech, nil
    91  }
    92  

View as plain text