  // key.
  func (s *Signer) CreateSignedX509(caCert *x509.Certificate, certSerial int, subjectKey *Verifier, subjectName *pkix.Name) (*x509.Certificate, error) {
  	template := prepareX509Template(subjectName)
++	template.SerialNumber = new(big.Int).SetInt64(int64(certSerial))
  
  	der, err := x509.CreateCertificate(rand.Reader, template, caCert, subjectKey.ec, s.ec)
  	if err != nil {
  		return nil, err
  	}
  	return x509.ParseCertificate(der)
-@@ -783,55 +805,63 @@ type Keys struct {
+ }
+ 
+ // marshalECDSA_SHA_SigningKeyV1 encodes a private key as a protobuf message.
+ func marshalECDSA_SHA_SigningKeyV1(k *ecdsa.PrivateKey) *ECDSA_SHA_SigningKeyV1 {
+ 	return &ECDSA_SHA_SigningKeyV1{
+ 		Curve:     NamedEllipticCurve_PRIME256_V1.Enum(),
+ 		EcPrivate: k.D.Bytes(),
+ 		EcPublic:  elliptic.Marshal(k.Curve, k.X, k.Y),
+ 	}
+ 
+ }
+ 
+ // MarshalSignerProto encodes a signing key as a CryptoKey protobuf message.
+ func MarshalSignerProto(s *Signer) (*CryptoKey, error) {
+ 	m := marshalECDSA_SHA_SigningKeyV1(s.ec)
+-	defer zeroBytes(m.EcPrivate)
++	defer ZeroBytes(m.EcPrivate)
+ 
+ 	b, err := proto.Marshal(m)
+ 	if err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	ck := &CryptoKey{
+ 		Version:   CryptoVersion_CRYPTO_VERSION_1.Enum(),
+ 		Purpose:   CryptoKey_SIGNING.Enum(),
+ 		Algorithm: CryptoKey_ECDSA_SHA.Enum(),
+ 		Key:       b,
+ 	}
+ 	return ck, nil
+ }
+ 
+ // marshalECDSA_SHA_VerifyingKeyV1 encodes a public key as a protobuf message.
+ func marshalECDSA_SHA_VerifyingKeyV1(k *ecdsa.PublicKey) *ECDSA_SHA_VerifyingKeyV1 {
+ 	return &ECDSA_SHA_VerifyingKeyV1{
+ 		Curve:    NamedEllipticCurve_PRIME256_V1.Enum(),
+ 		EcPublic: elliptic.Marshal(k.Curve, k.X, k.Y),
+@@ -275,41 +268,41 @@ func MarshalPublicSignerProto(s *Signer) *CryptoKey {
+ func MarshalVerifierProto(v *Verifier) *CryptoKey {
+ 	return marshalPublicKeyProto(v.ec)
+ }
+ 
+ // UnmarshalSignerProto decodes a signing key from a CryptoKey protobuf
+ // message.
+ func UnmarshalSignerProto(ck *CryptoKey) (*Signer, error) {
+ 	if *ck.Version != CryptoVersion_CRYPTO_VERSION_1 {
+ 		return nil, newError("bad version")
+ 	}
+ 
+ 	if *ck.Purpose != CryptoKey_SIGNING {
+ 		return nil, newError("bad purpose")
+ 	}
+ 
+ 	if *ck.Algorithm != CryptoKey_ECDSA_SHA {
+ 		return nil, newError("bad algorithm")
+ 	}
+ 
+ 	k := new(ECDSA_SHA_SigningKeyV1)
+-	defer zeroBytes(k.EcPrivate)
++	defer ZeroBytes(k.EcPrivate)
+ 	if err := proto.Unmarshal(ck.Key, k); err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	if *k.Curve != NamedEllipticCurve_PRIME256_V1 {
+ 		return nil, newError("bad Curve")
+ 	}
+ 
+ 	s := new(Signer)
+ 	s.ec = new(ecdsa.PrivateKey)
+ 	s.ec.D = new(big.Int).SetBytes(k.EcPrivate)
+ 	s.ec.Curve = elliptic.P256()
+ 	s.ec.X, s.ec.Y = elliptic.Unmarshal(elliptic.P256(), k.EcPublic)
+ 	return s, nil
+ }
+ 
+ // CreateHeader encodes the version and a key hint into a CryptoHeader.
+ func (s *Signer) CreateHeader() (*CryptoHeader, error) {
+ 	k := marshalECDSA_SHA_VerifyingKeyV1(&s.ec.PublicKey)
+ 	b, err := proto.Marshal(k)
+@@ -633,41 +626,41 @@ func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
+ 	s := cipher.NewCTR(block, ed.Iv)
+ 	data := make([]byte, len(ed.Ciphertext))
+ 	s.XORKeyStream(data, ed.Ciphertext)
+ 	return data, nil
+ }
+ 
+ // marshalAES_CTR_HMAC_SHA_CryptingKeyV1 encodes a private AES/HMAC key pair
+ // into a protobuf message.
+ func marshalAES_CTR_HMAC_SHA_CryptingKeyV1(c *Crypter) *AES_CTR_HMAC_SHA_CryptingKeyV1 {
+ 	return &AES_CTR_HMAC_SHA_CryptingKeyV1{
+ 		Mode:        CryptoCipherMode_CIPHER_MODE_CTR.Enum(),
+ 		AesPrivate:  c.aesKey,
+ 		HmacPrivate: c.hmacKey,
+ 	}
+ }
+ 
+ // MarshalCrypterProto encodes a Crypter as a CryptoKey protobuf message.
+ func MarshalCrypterProto(c *Crypter) (*CryptoKey, error) {
+ 	k := marshalAES_CTR_HMAC_SHA_CryptingKeyV1(c)
+ 
+-	// Note that we don't need to call zeroBytes on k.AesPrivate or
++	// Note that we don't need to call ZeroBytes on k.AesPrivate or
+ 	// k.HmacPrivate, since they're just slice references to the underlying
+ 	// keys.
+ 	m, err := proto.Marshal(k)
+ 	if err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	ck := &CryptoKey{
+ 		Version:   CryptoVersion_CRYPTO_VERSION_1.Enum(),
+ 		Purpose:   CryptoKey_CRYPTING.Enum(),
+ 		Algorithm: CryptoKey_AES_CTR_HMAC_SHA.Enum(),
+ 		Key:       m,
+ 	}
+ 
+ 	return ck, nil
+ }
+ 
+ // UnmarshalCrypterProto decodes a crypting key from a CryptoKey protobuf
+ // message.
+ func UnmarshalCrypterProto(ck *CryptoKey) (*Crypter, error) {
+@@ -688,41 +681,41 @@ func UnmarshalCrypterProto(ck *CryptoKey) (*Crypter, error) {
+ 		return nil, err
+ 	}
+ 
+ 	if *k.Mode != CryptoCipherMode_CIPHER_MODE_CTR {
+ 		return nil, newError("bad cipher mode")
+ 	}
+ 
+ 	c := new(Crypter)
+ 	c.aesKey = k.AesPrivate
+ 	c.hmacKey = k.HmacPrivate
+ 	return c, nil
+ }
+ 
+ // CreateHeader instantiates and fills in a header for this crypting key.
+ func (c *Crypter) CreateHeader() (*CryptoHeader, error) {
+ 	k := marshalAES_CTR_HMAC_SHA_CryptingKeyV1(c)
+ 	b, err := proto.Marshal(k)
+ 	if err != nil {
+ 		return nil, err
+ 	}
+-	defer zeroBytes(b)
++	defer ZeroBytes(b)
+ 
+ 	h := sha1.Sum(b)
+ 	ch := &CryptoHeader{
+ 		Version: CryptoVersion_CRYPTO_VERSION_1.Enum(),
+ 		KeyHint: h[:4],
+ 	}
+ 
+ 	return ch, nil
+ 
+ }
+ 
+ // GenerateDeriver generates a deriver with a fresh secret.
+ func GenerateDeriver() (*Deriver, error) {
+ 	d := new(Deriver)
+ 	d.secret = make([]byte, deriverSecretSize)
+ 	if _, err := rand.Read(d.secret); err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	return d, nil
+@@ -734,41 +727,41 @@ func (d *Deriver) Derive(salt, context, material []byte) error {
+ 	f := hkdf.New(sha256.New, d.secret, salt, context)
+ 	if _, err := f.Read(material); err != nil {
+ 		return err
+ 	}
+ 
+ 	return nil
+ }
+ 
+ // marshalHMAC_SHA_DerivingKeyV1 encodes a deriving key as a protobuf message.
+ func marshalHMAC_SHA_DerivingKeyV1(d *Deriver) *HMAC_SHA_DerivingKeyV1 {
+ 	return &HMAC_SHA_DerivingKeyV1{
+ 		Mode:        CryptoDerivingMode_DERIVING_MODE_HKDF.Enum(),
+ 		HmacPrivate: d.secret,
+ 	}
+ }
+ 
+ // MarshalDeriverProto encodes a Deriver as a CryptoKey protobuf message.
+ func MarshalDeriverProto(d *Deriver) (*CryptoKey, error) {
+ 	k := marshalHMAC_SHA_DerivingKeyV1(d)
+ 
+-	// Note that we don't need to call zeroBytes on k.HmacPrivate since
++	// Note that we don't need to call ZeroBytes on k.HmacPrivate since
+ 	// it's just a slice reference to the underlying keys.
+ 	m, err := proto.Marshal(k)
+ 	if err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	ck := &CryptoKey{
+ 		Version:   CryptoVersion_CRYPTO_VERSION_1.Enum(),
+ 		Purpose:   CryptoKey_DERIVING.Enum(),
+ 		Algorithm: CryptoKey_HMAC_SHA.Enum(),
+ 		Key:       m,
+ 	}
+ 
+ 	return ck, nil
+ }
+ 
+ // UnmarshalDeriverProto decodes a deriving key from a CryptoKey protobuf
+ // message.
+ func UnmarshalDeriverProto(ck *CryptoKey) (*Deriver, error) {
+ 	if *ck.Version != CryptoVersion_CRYPTO_VERSION_1 {
+@@ -805,86 +798,76 @@ type Keys struct {
  	keyTypes KeyType
  
  	SigningKey   *Signer

 	return path.Join(k.dir, "cert")
 }
 
+// SetMyKeyPath sets path for stored keys.
#*
#* author: Tom Roeder
#* email: tmroeder@google.com
#* date: 2014-11-13T10:44:55-0800
#*
#- Don't use "My" in function names. Also, it looks like go fmt hasn't been run
#- on this file. And it looks like these functions aren't used anywhere anymore,
#- so they should be removed.
#-
#*
#* author: John Manferdelli
#* email: johnmanferdelli@hotmail.com
#* date: 2014-11-14T14:21:18-0800
#*
#- OK.
#-
+func (k *Keys) SetMyKeyPath(dir_name string) {
+	k.dir= dir_name;
+}
+
+// SetKeyType sets key type
+func (k *Keys) SetKeyType(types KeyType) {
+	k.keyTypes= types;
+}
+
 // PBEKeysetPath returns the path for stored keys.
 func (k *Keys) PBEKeysetPath() string {
 	if k.dir == "" {
 		return ""
 	}
-
 	return path.Join(k.dir, "keys")
 }
 

 
 	return path.Join(k.dir, "delegation")
 }
 
-// zeroBytes clears the bytes in a slice.
-func zeroBytes(b []byte) {
+// ZeroBytes clears the bytes in a slice.
+func ZeroBytes(b []byte) {
 	for i := range b {
 		b[i] = 0
 	}
 }
 
 // NewTemporaryKeys creates a new Keys structure with the specified keys.
 func NewTemporaryKeys(keyTypes KeyType) (*Keys, error) {
 	k := &Keys{
 		keyTypes: keyTypes,
 	}
 	if k.keyTypes == 0 || (k.keyTypes & ^Signing & ^Crypting & ^Deriving != 0) {
 		return nil, newError("bad key type")
 	}
 
 	var err error
 	if k.keyTypes&Signing == Signing {
 		k.SigningKey, err = GenerateSigner()
 		if err != nil {
 			return nil, err
 		}
@@ -892,40 +875,77 @@ func NewTemporaryKeys(keyTypes KeyType) (*Keys, error) {
 		k.VerifyingKey = k.SigningKey.GetVerifier()
 	}
 
 	if k.keyTypes&Crypting == Crypting {
 		k.CryptingKey, err = GenerateCrypter()
 		if err != nil {
 			return nil, err
 		}
 	}
 
 	if k.keyTypes&Deriving == Deriving {
 		k.DerivingKey, err = GenerateDeriver()
 		if err != nil {
 			return nil, err
 		}
 	}
 
 	return k, nil
 }
 
+// NewSignedOnDiskPBEKeys creates the same type of keys as NewOnDiskPBEKeys but
+// signs a certificate for the signer with the provided Keys, which must have
+// both a SigningKey and a Certificate.
+func NewSignedOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix.Name, serial int, signer *Keys) (*Keys, error) {
+	if signer == nil || name == nil {
+		return nil, newError("must supply a signer and a name")
+	}
+
+	if signer.Cert == nil || signer.SigningKey == nil {
+		return nil, newError("the signing key must have a SigningKey and a Cert")
+	}
+
+	if keyTypes & ^Signing != 0 {
+		return nil, newError("can't sign a key that has no signer")
+	}
+
+	k, err := NewOnDiskPBEKeys(keyTypes, password, path, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// If there's already a cert, then this means that there was already a
+	// keyset on disk, so don't create a new signed certificate.
+	if k.Cert == nil {
+		k.Cert, err = signer.SigningKey.CreateSignedX509(signer.Cert, serial, k.VerifyingKey, name)
+		if err != nil {
+			return nil, err
+		}
+
+		if err = util.WritePath(k.X509Path(), k.Cert.Raw, 0777, 0666); err != nil {
+			return nil, err
+		}
+	}
+
+	return k, nil
+}
+
 // NewOnDiskPBEKeys creates a new Keys structure with the specified key types
 // store under PBE on disk. If keys are generated and name is not nil, then a
 // self-signed x509 certificate will be generated and saved as well.
 func NewOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix.Name) (*Keys, error) {
 	if keyTypes == 0 || (keyTypes & ^Signing & ^Crypting & ^Deriving != 0) {
 		return nil, newError("bad key type")
 	}
 
 	if path == "" {
 		return nil, newError("bad init call: no path for keys")
 	}
 
 	k := &Keys{
 		keyTypes: keyTypes,
 		dir:      path,
 	}
 
 	if len(password) == 0 {
 		// This means there's no secret information: just load a public
 		// verifying key.
@@ -946,144 +966,146 @@ func NewOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix
 		}
 	} else {
 		// There are two different types of keysets: in one there's
 		// just a Signer, so we use an encrypted PEM format. In the
 		// other, there are multiple keys, so we use a custom protobuf
 		// format.
 		if k.keyTypes & ^Signing != 0 {
 			// Check to see if there are already keys.
 			f, err := os.Open(k.PBEKeysetPath())
 			if err == nil {
 				defer f.Close()
 				ks, err := ioutil.ReadAll(f)
 				if err != nil {
 					return nil, err
 				}
 
 				data, err := PBEDecrypt(ks, password)
 				if err != nil {
 					return nil, err
 				}
-				defer zeroBytes(data)
+				defer ZeroBytes(data)
 
 				var cks CryptoKeyset
 				if err = proto.Unmarshal(data, &cks); err != nil {
 					return nil, err
 				}
 
 				// TODO(tmroeder): defer zeroKeyset(&cks)
 
 				ktemp, err := UnmarshalKeyset(&cks)
 				if err != nil {
 					return nil, err
 				}
 
+				// Note that this loads the certificate if it's
+				// present, and it returns nil otherwise.
 				err = k.loadCert()
 				if err != nil {
 					return nil, err
 				}
 
 				k.SigningKey = ktemp.SigningKey
 				k.VerifyingKey = ktemp.VerifyingKey
 				k.CryptingKey = ktemp.CryptingKey
 				k.DerivingKey = ktemp.DerivingKey
 			} else {
 				// Create and store a new set of keys.
 				k, err = NewTemporaryKeys(keyTypes)
 				if err != nil {
 					return nil, err
 				}
 
 				k.dir = path
 
 				cks, err := MarshalKeyset(k)
 				if err != nil {
 					return nil, err
 				}
 
 				// TODO(tmroeder): defer zeroKeyset(cks)
 
 				m, err := proto.Marshal(cks)
 				if err != nil {
 					return nil, err
 				}
-				defer zeroBytes(m)
+				defer ZeroBytes(m)
 
 				enc, err := PBEEncrypt(m, password)
 				if err != nil {
 					return nil, err
 				}
 
 				if err = util.WritePath(k.PBEKeysetPath(), enc, 0777, 0600); err != nil {
 					return nil, err
 				}
 
 				if k.SigningKey != nil && name != nil {
 					err = k.newCert(name)
 					if err != nil {
 						return nil, err
 					}
 				}
 			}
 		} else {
 			// There's just a signer, so do PEM encryption of the encoded key.
 			f, err := os.Open(k.PBESignerPath())
 			if err == nil {
 				defer f.Close()
 				// Read the signer.
 				ss, err := ioutil.ReadAll(f)
 				if err != nil {
 					return nil, err
 				}
 
 				pb, rest := pem.Decode(ss)
 				if pb == nil || len(rest) > 0 {
 					return nil, newError("decoding failure")
 				}
 
 				p, err := x509.DecryptPEMBlock(pb, password)
 				if err != nil {
 					return nil, err
 				}
-				defer zeroBytes(p)
+				defer ZeroBytes(p)
 
 				err = k.loadCert()
 				if err != nil {
 					return nil, err
 				}
 
 				if k.SigningKey, err = UnmarshalSignerDER(p); err != nil {
 					return nil, err
 				}
 				k.VerifyingKey = k.SigningKey.GetVerifier()
 			} else {
 				// Create a fresh key and store it to the PBESignerPath.
 				if k.SigningKey, err = GenerateSigner(); err != nil {
 					return nil, err
 				}
 
 				k.VerifyingKey = k.SigningKey.GetVerifier()
 				p, err := MarshalSignerDER(k.SigningKey)
 				if err != nil {
 					return nil, err
 				}
-				defer zeroBytes(p)
+				defer ZeroBytes(p)
 
 				pb, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", p, password, x509.PEMCipherAES128)
 				if err != nil {
 					return nil, err
 				}
 
 				pbes, err := util.CreatePath(k.PBESignerPath(), 0700, 0600)
 				if err != nil {
 					return nil, err
 				}
 				defer pbes.Close()
 
 				if err = pem.Encode(pbes, pb); err != nil {
 					return nil, err
 				}
 
 				if k.SigningKey != nil && name != nil {
 					err = k.newCert(name)
 					if err != nil {
 						return nil, err
@@ -1092,40 +1114,42 @@ func NewOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix
 			}
 		}
 	}
 
 	return k, nil
 }
 
 func (k *Keys) newCert(name *pkix.Name) (err error) {
 	k.Cert, err = k.SigningKey.CreateSelfSignedX509(name)
 	if err != nil {
 		return err
 	}
 	if err = util.WritePath(k.X509Path(), k.Cert.Raw, 0777, 0666); err != nil {
 		return err
 	}
 	return nil
 }
 
 func (k *Keys) loadCert() error {
 	f, err := os.Open(k.X509Path())
+	// Allow this operation to fail silently, since there isn't always a
+	// certificate available.
 	if err != nil {
 		return nil
 	}
