github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/newfileproxy/common/utility.go (about)

     1  // Copyright (c) 2016, Google, Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // File: utility.go
    16  
    17  package common;
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"crypto/elliptic"
    22  	"crypto/rand"
    23  	"crypto/x509"
    24  	"crypto/x509/pkix"
    25  	"log"
    26  	"math/big"
    27  	"time"
    28  
    29  	"github.com/golang/protobuf/proto"
    30  )
    31  
    32  
    33  
    34  func GenerateUserPublicKey() (*ecdsa.PrivateKey, error) {
    35  	return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    36  }
    37  
    38  func MakeUserKeyStructure(key *ecdsa.PrivateKey, userName string, signerPriv interface{},
    39  		signerCertificate *x509.Certificate) (*KeyData, error) {
    40  	keyData := new(KeyData)
    41  	notBefore := time.Now()
    42  	validFor := 365 * 24 * time.Hour
    43  	notAfter := notBefore.Add(validFor)
    44  	serialNumber := new(big.Int).SetInt64(1)
    45  	var subjectPub interface{}
    46  	subjectPub = key.Public()
    47   	cert, err := CreateKeyCertificate(*serialNumber, "Google", "", "US",
    48  			  signerPriv, signerCertificate, "", userName, "US", subjectPub,
    49  			  notBefore, notAfter, false,
    50  			  x509.KeyUsageCertSign|x509.KeyUsageKeyAgreement|x509.KeyUsageDigitalSignature)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	keyData.Cert = cert
    55  	keyData.Key = key
    56  	return keyData, nil
    57  }
    58  
    59  func SerializeUserKey(key *KeyData) ([]byte, error) {
    60  	keyMessage := new(UserKeyDataMessage)
    61  	keyMessage.Cert = key.Cert
    62  	blob, err := x509.MarshalECPrivateKey(key.Key)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	keyMessage.DerKey = blob
    67  	return proto.Marshal(keyMessage)
    68  }
    69  
    70  func ParseUserKey(in []byte) (*KeyData, error) {
    71  	key := new(KeyData)
    72  	keyMessage := new(UserKeyDataMessage)
    73  	err := proto.Unmarshal(in, keyMessage)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	key.Cert = keyMessage.Cert
    78  	key.Key, err = x509.ParseECPrivateKey(keyMessage.DerKey)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	return key, nil
    83  }
    84  
    85  // policyKey.SigningKey.GetSigner())
    86  // KeyUsage:     x509.KeyUsageCertSign | x509.KeyUsageKeyAgreement | x509.KeyUsageDigitalSignature,
    87  
    88  func CreateKeyCertificate(serialNumber big.Int,
    89  			  issuerCommonName string,
    90  			  issuerOrgName string,
    91  			  issuerCountry string,
    92  			  issuerKey interface{},
    93  			  parentCert *x509.Certificate,
    94  			  subjectOrgName string,
    95  			  subjectCommonName string,
    96  			  subjectCountry string,
    97  			  subjectKey interface{},
    98  			  notBefore time.Time,
    99  			  notAfter time.Time,
   100  			  isCA bool,
   101  			  keyUsage x509.KeyUsage) ([]byte, error)  {
   102  
   103  	x509SubjectName := &pkix.Name{
   104  		Organization:       []string{subjectOrgName},
   105  		CommonName:         subjectCommonName,
   106  		Country:            []string{subjectCountry},
   107  	}
   108  
   109  	x509IssuerName := &pkix.Name{
   110  		Organization:       []string{issuerOrgName},
   111  		CommonName:         issuerCommonName,
   112  		Country:            []string{issuerCountry},
   113  	}
   114  
   115  	certificateTemplate := x509.Certificate {
   116  		SerialNumber: &serialNumber,
   117  		Issuer:       *x509IssuerName,
   118  		Subject:      *x509SubjectName,
   119  		NotBefore:    notBefore,
   120  		NotAfter:     notAfter,
   121  		KeyUsage:     keyUsage,
   122  	}
   123  	if isCA {
   124  		certificateTemplate.BasicConstraintsValid = true
   125  		certificateTemplate.IsCA = true
   126  	}
   127  
   128  	if parentCert == nil {
   129  		parentCert = &certificateTemplate
   130  	}
   131  
   132  	cert, err := x509.CreateCertificate(rand.Reader, &certificateTemplate,
   133  				parentCert, subjectKey, issuerKey)
   134  	if err != nil {
   135  		log.Printf("Can't create certificate. Error: %v\n", err)
   136  		return nil, err
   137  	}
   138  	return cert, err
   139  }
   140  
   141  func VerifyNonceSignature(nonce []byte, s1 []byte, s2 []byte, certificate *x509.Certificate) bool {
   142  	r := new(big.Int)
   143  	s := new(big.Int)
   144  	r.SetBytes(s1)
   145  	s.SetBytes(s2)
   146  	return ecdsa.Verify(certificate.PublicKey.(*ecdsa.PublicKey), nonce, r, s)
   147  }
   148  
   149  func VerifyCertificateChain(root *x509.Certificate, intermediateCerts []*x509.Certificate,
   150  		cert *x509.Certificate) (bool, [][]*x509.Certificate, error) {
   151  	rootsPool := x509.NewCertPool()
   152  	rootsPool.AddCert(root)
   153  	intermediatesPool := x509.NewCertPool()
   154  	for i := 0; i< len(intermediateCerts); i++ {
   155  		intermediatesPool.AddCert(intermediateCerts[i])
   156  	}
   157  
   158  	opts := x509.VerifyOptions {
   159  		Intermediates: intermediatesPool,
   160  		Roots:   rootsPool,
   161  		KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
   162  	}
   163  
   164  	chain, err := cert.Verify(opts)
   165  	if err == nil {
   166  		return true, chain, err
   167  	}
   168  	return false, nil, err
   169  }
   170