...

Source file src/github.com/ThalesIgnite/crypto11/common.go

Documentation: github.com/ThalesIgnite/crypto11

     1  // Copyright 2017 Thales e-Security, Inc
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining
     4  // a copy of this software and associated documentation files (the
     5  // "Software"), to deal in the Software without restriction, including
     6  // without limitation the rights to use, copy, modify, merge, publish,
     7  // distribute, sublicense, and/or sell copies of the Software, and to
     8  // permit persons to whom the Software is furnished to do so, subject to
     9  // the following conditions:
    10  //
    11  // The above copyright notice and this permission notice shall be
    12  // included in all copies or substantial portions of the Software.
    13  //
    14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    15  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    16  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    17  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    18  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    19  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    20  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    21  
    22  package crypto11
    23  
    24  import (
    25  	"C"
    26  	"encoding/asn1"
    27  	"math/big"
    28  	"unsafe"
    29  
    30  	"github.com/miekg/pkcs11"
    31  	"github.com/pkg/errors"
    32  )
    33  
    34  func ulongToBytes(n uint) []byte {
    35  	return C.GoBytes(unsafe.Pointer(&n), C.sizeof_ulong) // ugh!
    36  }
    37  
    38  func bytesToUlong(bs []byte) (n uint) {
    39  	sliceSize := len(bs)
    40  	if sliceSize == 0 {
    41  		return 0
    42  	}
    43  
    44  	value := *(*uint)(unsafe.Pointer(&bs[0]))
    45  	if sliceSize > C.sizeof_ulong {
    46  		return value
    47  	}
    48  
    49  	// truncate the value to the # of bits present in the byte slice since
    50  	// the unsafe pointer will always grab/convert ULONG # of bytes
    51  	var mask uint
    52  	for i := 0; i < sliceSize; i++ {
    53  		mask |= 0xff << uint(i * 8)
    54  	}
    55  	return value & mask
    56  }
    57  
    58  func concat(slices ...[]byte) []byte {
    59  	n := 0
    60  	for _, slice := range slices {
    61  		n += len(slice)
    62  	}
    63  	r := make([]byte, n)
    64  	n = 0
    65  	for _, slice := range slices {
    66  		n += copy(r[n:], slice)
    67  	}
    68  	return r
    69  }
    70  
    71  // Representation of a *DSA signature
    72  type dsaSignature struct {
    73  	R, S *big.Int
    74  }
    75  
    76  // Populate a dsaSignature from a raw byte sequence
    77  func (sig *dsaSignature) unmarshalBytes(sigBytes []byte) error {
    78  	if len(sigBytes) == 0 || len(sigBytes)%2 != 0 {
    79  		return errors.New("DSA signature length is invalid from token")
    80  	}
    81  	n := len(sigBytes) / 2
    82  	sig.R, sig.S = new(big.Int), new(big.Int)
    83  	sig.R.SetBytes(sigBytes[:n])
    84  	sig.S.SetBytes(sigBytes[n:])
    85  	return nil
    86  }
    87  
    88  // Populate a dsaSignature from DER encoding
    89  func (sig *dsaSignature) unmarshalDER(sigDER []byte) error {
    90  	if rest, err := asn1.Unmarshal(sigDER, sig); err != nil {
    91  		return errors.WithMessage(err, "DSA signature contains invalid ASN.1 data")
    92  	} else if len(rest) > 0 {
    93  		return errors.New("unexpected data found after DSA signature")
    94  	}
    95  	return nil
    96  }
    97  
    98  // Return the DER encoding of a dsaSignature
    99  func (sig *dsaSignature) marshalDER() ([]byte, error) {
   100  	return asn1.Marshal(*sig)
   101  }
   102  
   103  // Compute *DSA signature and marshal the result in DER form
   104  func (c *Context) dsaGeneric(key pkcs11.ObjectHandle, mechanism uint, digest []byte) ([]byte, error) {
   105  	var err error
   106  	var sigBytes []byte
   107  	var sig dsaSignature
   108  	mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(mechanism, nil)}
   109  	err = c.withSession(func(session *pkcs11Session) error {
   110  		if err = c.ctx.SignInit(session.handle, mech, key); err != nil {
   111  			return err
   112  		}
   113  		sigBytes, err = c.ctx.Sign(session.handle, digest)
   114  		return err
   115  	})
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	err = sig.unmarshalBytes(sigBytes)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	return sig.marshalDER()
   125  }
   126  

View as plain text