...

Source file src/github.com/sassoftware/relic/token/p11token/certs.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/sha1"
    21  	"crypto/x509"
    22  	"errors"
    23  	"fmt"
    24  
    25  	"github.com/miekg/pkcs11"
    26  	"github.com/sassoftware/relic/signers/sigerrors"
    27  )
    28  
    29  var newCertAttrs = []*pkcs11.Attribute{
    30  	pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
    31  	pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
    32  	pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
    33  	pkcs11.NewAttribute(pkcs11.CKA_CERTIFICATE_TYPE, pkcs11.CKC_X_509),
    34  }
    35  
    36  func (tk *Token) ImportCertificate(cert *x509.Certificate, labelBase string) error {
    37  	fingerprint := sha1.Sum(cert.Raw)
    38  	if labelBase == "" {
    39  		return errors.New("label is required")
    40  	}
    41  	// make a label from the private key label plus the certificate fingerprint
    42  	label := fmt.Sprintf("%s_chain_%x", labelBase, fingerprint[:8])
    43  	tk.mutex.Lock()
    44  	defer tk.mutex.Unlock()
    45  	if err := tk.certExists(label); err != nil {
    46  		return err
    47  	}
    48  	keyID := makeKeyID()
    49  	if keyID == nil {
    50  		return errors.New("failed to make key ID")
    51  	}
    52  	attrs := []*pkcs11.Attribute{
    53  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
    54  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
    55  		pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, cert.RawSubject),
    56  		pkcs11.NewAttribute(pkcs11.CKA_ISSUER, cert.RawIssuer),
    57  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, cert.Raw),
    58  	}
    59  	attrs = append(attrs, newCertAttrs...)
    60  	_, err := tk.ctx.CreateObject(tk.sh, attrs)
    61  	return err
    62  }
    63  
    64  func (tk *Token) certExists(label string) error {
    65  	attrs := []*pkcs11.Attribute{
    66  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
    67  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
    68  	}
    69  	objects, err := tk.findObject(attrs)
    70  	if err != nil {
    71  		return err
    72  	} else if len(objects) != 0 {
    73  		return sigerrors.ErrExist
    74  	} else {
    75  		return nil
    76  	}
    77  }
    78  
    79  func (key *Key) ImportCertificate(cert *x509.Certificate) error {
    80  	keyID, handle, err := key.findCertificate()
    81  	if err != nil {
    82  		return err
    83  	} else if handle != 0 {
    84  		return sigerrors.ErrExist
    85  	}
    86  	label := key.getLabel()
    87  	if label == "" {
    88  		return errors.New("label is required")
    89  	}
    90  	attrs := []*pkcs11.Attribute{
    91  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
    92  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
    93  		pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, cert.RawSubject),
    94  		pkcs11.NewAttribute(pkcs11.CKA_ISSUER, cert.RawIssuer),
    95  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, cert.Raw),
    96  	}
    97  	attrs = append(attrs, newCertAttrs...)
    98  	key.token.mutex.Lock()
    99  	defer key.token.mutex.Unlock()
   100  	_, err = key.token.ctx.CreateObject(key.token.sh, attrs)
   101  	return err
   102  }
   103  
   104  func (key *Key) findCertificate() (keyID []byte, handle pkcs11.ObjectHandle, err error) {
   105  	keyID = key.GetID()
   106  	if len(keyID) == 0 {
   107  		return nil, 0, errors.New("no keyID")
   108  	}
   109  	key.token.mutex.Lock()
   110  	defer key.token.mutex.Unlock()
   111  	attrs := []*pkcs11.Attribute{
   112  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
   113  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
   114  	}
   115  	objects, err := key.token.findObject(attrs)
   116  	if err != nil {
   117  		return nil, 0, err
   118  	}
   119  	if len(objects) == 0 {
   120  		return keyID, 0, nil
   121  	}
   122  	return keyID, objects[0], nil
   123  }
   124  

View as plain text