예제 #1
0
func doKeyInfo() {
	b, err := ioutil.ReadFile(*kiFilename)
	log.Fatale(err, "cannot read keyfile")

	var sk [64]byte
	isPrivate, err := spki.LoadKeyFile(bytes.NewReader(b), &sk)
	log.Fatale(err, "cannot decode keyfile")

	if isPrivate {
		fmt.Fprintf(os.Stderr, ";; Ed25519 Private Key\n")
	} else {
		fmt.Fprintf(os.Stderr, ";; Ed25519 Public Key\n")
	}
	fmt.Fprintf(os.Stderr, ";; Fingerprint: %v\n", hexFormat(sk[32:64]))
	fmt.Fprintf(os.Stderr, ";; Fingerprint (b32): %v\n", spki.EncodeB32(sk[32:64]))
	fmt.Fprintf(os.Stderr, "%s", prefix(randomart.Generate(sk[32:64], " Ed25519").String()))

	var cpk [32]byte
	var edpub [32]byte
	copy(edpub[:], sk[32:64])
	if !extra25519.PublicKeyToCurve25519(&cpk, &edpub) {
		log.Fatal("Cannot derive Curve25519 public key.")
	}

	fmt.Fprintf(os.Stderr, ";; Curve25519 Fingerprint: %v\n", hexFormat(cpk[:]))
	fmt.Fprintf(os.Stderr, ";; Curve25519 Fingerprint (b32): %v\n", spki.EncodeB32(cpk[:]))
}
예제 #2
0
func TestKeys(t *testing.T) {
	var cpriv, cpub, cpub2 [32]byte
	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if assert.NoError(t, err) {
		assert.True(t, extra25519.PublicKeyToCurve25519(&cpub, pub), "Calling PublicKeyToCurve25519 failed")
		extra25519.PrivateKeyToCurve25519(&cpriv, priv)
		curve25519.ScalarBaseMult(&cpub2, &cpriv)
		assert.Equal(t, cpub, cpub2)
	}
}
예제 #3
0
파일: key.go 프로젝트: read-later/bazil
// loadOrGenerateKeys reads the master signing key from the global
// state in DB, (generating one if it's not already there), and
// generates the boxing keys based on it.
//
// This is meant to be called exactly once at startup time.
func loadOrGenerateKeys(db *bolt.DB) (*CryptoKeys, error) {
	var k CryptoKeys

	getKey := func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(tokens.BucketBazil))
		val := bucket.Get([]byte(tokens.GlobalStateKey))
		if val == nil {
			// have not generated a key yet
			return nil
		}
		if len(val) != ed25519.PrivateKeySize {
			return fmt.Errorf("master key wrong is the wrong size: length=%d", len(val))
		}
		var sigPriv [ed25519.PrivateKeySize]byte
		copy(sigPriv[:], val)
		k.Sign.Priv = &sigPriv
		return nil
	}
	if err := db.View(getKey); err != nil {
		return nil, err
	}

	if k.Sign.Priv == nil {
		// did not load keys from database
		var err error
		_, signPriv, err := ed25519.GenerateKey(rand.Reader)
		if err != nil {
			return nil, err
		}
		k.Sign.Priv = signPriv

		// save it for future runs
		putKey := func(tx *bolt.Tx) error {
			bucket := tx.Bucket([]byte(tokens.BucketBazil))
			return bucket.Put([]byte(tokens.GlobalStateKey), signPriv[:])
		}
		if err := db.Update(putKey); err != nil {
			return nil, err
		}
	}

	k.Sign.Pub = extractEd25519Pubkey(k.Sign.Priv)

	// generate other keys from it
	k.Box.Priv = &[32]byte{}
	extra25519.PrivateKeyToCurve25519(k.Box.Priv, k.Sign.Priv)
	k.Box.Pub = &[32]byte{}
	extra25519.PublicKeyToCurve25519(k.Box.Pub, k.Sign.Pub)
	return &k, nil
}
예제 #4
0
파일: client.go 프로젝트: jwilkins/pond
func (contact *Contact) processKeyExchange(kxsBytes []byte, testing, simulateOldClient, disableV2Ratchet bool) error {
	var kxs pond.SignedKeyExchange
	if err := proto.Unmarshal(kxsBytes, &kxs); err != nil {
		return err
	}

	var sig [64]byte
	if len(kxs.Signature) != len(sig) {
		return errors.New("invalid signature length")
	}
	copy(sig[:], kxs.Signature)

	var kx pond.KeyExchange
	if err := proto.Unmarshal(kxs.Signed, &kx); err != nil {
		return err
	}

	if len(kx.PublicKey) != len(contact.theirPub) {
		return errors.New("invalid public key")
	}
	copy(contact.theirPub[:], kx.PublicKey)

	if !ed25519.Verify(&contact.theirPub, kxs.Signed, &sig) {
		return errors.New("invalid signature")
	}

	contact.theirServer = *kx.Server
	if _, _, err := parseServer(contact.theirServer, testing); err != nil {
		return err
	}

	group, ok := new(bbssig.Group).Unmarshal(kx.Group)
	if !ok {
		return errors.New("invalid group")
	}
	if contact.myGroupKey, ok = new(bbssig.MemberKey).Unmarshal(group, kx.GroupKey); !ok {
		return errors.New("invalid group key")
	}

	if len(kx.IdentityPublic) != len(contact.theirIdentityPublic) {
		return errors.New("invalid public identity")
	}
	copy(contact.theirIdentityPublic[:], kx.IdentityPublic)

	if simulateOldClient {
		kx.Dh1 = nil
	}

	if len(kx.Dh1) == 0 {
		// They are using an old-style ratchet. We have to extract the
		// private value from the Ratchet in order to use it with the
		// old code.
		contact.lastDHPrivate = contact.ratchet.GetKXPrivateForTransition()
		if len(kx.Dh) != len(contact.theirCurrentDHPublic) {
			return errors.New("invalid public DH value")
		}
		copy(contact.theirCurrentDHPublic[:], kx.Dh)
		contact.ratchet = nil
	} else {
		// If the identity and ed25519 public keys are the same (modulo
		// isomorphism) then the contact is using the v2 ratchet.
		var ed25519Public, curve25519Public [32]byte
		copy(ed25519Public[:], kx.PublicKey)
		extra25519.PublicKeyToCurve25519(&curve25519Public, &ed25519Public)
		v2 := !disableV2Ratchet && bytes.Equal(curve25519Public[:], kx.IdentityPublic[:])
		if err := contact.ratchet.CompleteKeyExchange(&kx, v2); err != nil {
			return err
		}
	}

	contact.generation = *kx.Generation

	return nil
}