// ImportVerified imports a verified key under the label. The original // signature data is preserved in the keystore. func (s *KeyStore) ImportVerified(label string, signedKey []byte) bool { var pub []byte if !s.Valid(true) || s.Has(label) { return false } var vkey VerifiedKey _, err := asn1.Unmarshal(signedKey, &vkey) if err != nil { return false } var signerLabel string if bytes.Equal(vkey.Signer, s.PublicKey) { signerLabel = "self" pub = s.PublicKey } else { var ok bool signerLabel, ok = s.FindPublic(vkey.Signer) if !ok { return false } pub = s.Keys[signerLabel].Keys } if signerLabel == "" || pub == nil { return false } else if _, ok := s.VerifyKeySignature(signerLabel); !ok { return false } pubkey, err := public.UnmarshalPublic(pub) if err != nil { return false } signatureData := vkey.SignatureData() if !public.Verify(pubkey, signatureData, vkey.Signature) { return false } rec := &PublicKeyRecord{ Label: label, Version: KeyStoreVersion, Timestamp: time.Now().Unix(), Keys: vkey.Public, KeySignature: vkey.Signature, KeySigner: pub, SignatureTime: vkey.Timestamp, } s.Keys[label] = rec return true }
// IsSelfSigned returns true if the verified key is self-signed. func (vkey *VerifiedKey) IsSelfSigned() bool { if !bytes.Equal(vkey.Public, vkey.Signer) { return false } signer, err := public.UnmarshalPublic(vkey.Signer) if err != nil { return false } sigData := vkey.SignatureData() return public.Verify(signer, sigData, vkey.Signature) }
// Verify validates that the message was signed by the named public // key. func (s *KeyStore) Verify(label string, message, sig []byte) bool { if !s.Valid(true) { return false } else if !s.Has(label) { return false } pub := s.getPublic(label) if pub == nil { return false } return public.Verify(pub, message, sig) }
// AddKey adds the new peer key to the keystore, signing it with the // owner's key. If the keystore is locked, this will fail. func (s *KeyStore) AddKey(label string, peer []byte, metadata map[string]string) bool { if !s.Valid(true) { return false } else if s.Has(label) { return false } else if s.Locked() { return false } else if _, err := public.UnmarshalPublic(peer); err != nil { return false } signTime := time.Now().Unix() vkey := &VerifiedKey{ Public: peer, Signer: s.PublicKey, Timestamp: signTime, } signatureData := vkey.SignatureData() sig, ok := public.Sign(s.privateKey, signatureData) if !ok { return false } if !public.Verify(s.privateKey.PublicKey, signatureData, sig) { return false } metadataCopy := map[string]string{} for k, v := range metadata { metadataCopy[k] = v } s.Keys[label] = &PublicKeyRecord{ Label: label, Timestamp: time.Now().Unix(), Keys: peer, KeySignature: sig, KeySigner: s.PublicKey, SignatureTime: signTime, Metadata: metadataCopy, } return true }
// VerifyKeySignature authenticates the signature on the key indicated // by label. If the label is self, Verify returns true as that label // is assumed always valid. func (s *KeyStore) VerifyKeySignature(label string) (string, bool) { if !s.Valid(true) { return "", false } if label == "self" { return "self", true } rec := s.Keys[label] var signerLabel string var vkey = &VerifiedKey{ Public: rec.Keys, Signature: rec.KeySignature, Timestamp: rec.SignatureTime, } if bytes.Equal(rec.KeySigner, s.PublicKey) { vkey.Signer = s.PublicKey signerLabel = "self" } else { var ok bool signerLabel, ok = s.FindPublic(rec.KeySigner) if !ok { return "", false } vkey.Signer = s.Keys[signerLabel].Keys } pub, err := public.UnmarshalPublic(vkey.Signer) if err != nil { return "", false } signatureData := vkey.SignatureData() if !public.Verify(pub, signatureData, vkey.Signature) { return "", false } return signerLabel, true }