uncommitted - golang-github-twstrike-otr3
Ready changes
Summary
Import uploads missing from VCS:Diff
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 845ca06..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.pc
diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches
new file mode 100644
index 0000000..6857a8d
--- /dev/null
+++ b/.pc/.quilt_patches
@@ -0,0 +1 @@
+debian/patches
diff --git a/.pc/.quilt_series b/.pc/.quilt_series
new file mode 100644
index 0000000..c206706
--- /dev/null
+++ b/.pc/.quilt_series
@@ -0,0 +1 @@
+series
diff --git a/.pc/.version b/.pc/.version
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/.pc/.version
@@ -0,0 +1 @@
+2
diff --git a/.pc/applied-patches b/.pc/applied-patches
new file mode 100644
index 0000000..8cfcc44
--- /dev/null
+++ b/.pc/applied-patches
@@ -0,0 +1,2 @@
+test_location.patch
+go-1.11.patch
diff --git a/.pc/go-1.11.patch/ake.go b/.pc/go-1.11.patch/ake.go
new file mode 100644
index 0000000..ec8c367
--- /dev/null
+++ b/.pc/go-1.11.patch/ake.go
@@ -0,0 +1,389 @@
+package otr3
+
+import (
+ "crypto/hmac"
+ "crypto/subtle"
+ "io"
+ "math/big"
+ "time"
+)
+
+type ake struct {
+ secretExponent *big.Int
+ ourPublicValue *big.Int
+ theirPublicValue *big.Int
+
+ // TODO: why this number here?
+ r [16]byte
+
+ encryptedGx []byte
+
+ // SIZE: this should always be version.hash2Length
+ xhashedGx []byte
+
+ revealKey akeKeys
+ sigKey akeKeys
+
+ state authState
+ keys keyManagementContext
+
+ lastStateChange time.Time
+}
+
+func (c *Conversation) ensureAKE() {
+ if c.ake != nil {
+ return
+ }
+
+ c.initAKE()
+}
+
+func (c *Conversation) initAKE() {
+ c.ake = &ake{
+ state: authStateNone{},
+ }
+}
+
+func (c *Conversation) calcAKEKeys(s *big.Int) {
+ c.ssid, c.ake.revealKey, c.ake.sigKey = calculateAKEKeys(s, c.version)
+}
+
+func (c *Conversation) setSecretExponent(val *big.Int) {
+ c.ake.secretExponent = new(big.Int).Set(val)
+ c.ake.ourPublicValue = modExp(g1, val)
+}
+
+func (c *Conversation) calcDHSharedSecret() *big.Int {
+ return modExp(c.ake.theirPublicValue, c.ake.secretExponent)
+}
+
+func (c *Conversation) generateEncryptedSignature(key *akeKeys) ([]byte, error) {
+ verifyData := appendAll(c.ake.ourPublicValue, c.ake.theirPublicValue, c.ourCurrentKey.PublicKey(), c.ake.keys.ourKeyID)
+
+ mb := sumHMAC(key.m1, verifyData, c.version)
+ xb, err := c.calcXb(key, mb)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return appendData(nil, xb), nil
+}
+func appendAll(one, two *big.Int, publicKey PublicKey, keyID uint32) []byte {
+ return appendWord(append(appendMPI(appendMPI(nil, one), two), publicKey.serialize()...), keyID)
+}
+
+func fixedSize(s int, v []byte) []byte {
+ if len(v) < s {
+ vv := make([]byte, s)
+ copy(vv, v)
+ return vv
+ }
+ return v
+}
+
+func (c *Conversation) calcXb(key *akeKeys, mb []byte) ([]byte, error) {
+ xb := c.ourCurrentKey.PublicKey().serialize()
+ xb = appendWord(xb, c.ake.keys.ourKeyID)
+
+ sigb, err := c.ourCurrentKey.Sign(c.rand(), mb)
+ if err == io.ErrUnexpectedEOF {
+ return nil, errShortRandomRead
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ // this error can't happen, since key.c is fixed to the correct size
+ xb, _ = encrypt(fixedSize(c.version.keyLength(), key.c), append(xb, sigb...))
+
+ return xb, nil
+}
+
+// dhCommitMessage = bob = x
+// Bob ---- DH Commit -----------> Alice
+func (c *Conversation) dhCommitMessage() ([]byte, error) {
+ c.initAKE()
+ c.ake.keys.ourKeyID = 0
+
+ // TODO: where does this 40 come from?
+ x, err := c.randMPI(make([]byte, 40))
+ if err != nil {
+ return nil, err
+ }
+
+ c.setSecretExponent(x)
+ wipeBigInt(x)
+
+ if err := c.randomInto(c.ake.r[:]); err != nil {
+ return nil, err
+ }
+
+ // this can't return an error, since ake.r is of a fixed size that is always correct
+ c.ake.encryptedGx, _ = encrypt(c.ake.r[:], appendMPI(nil, c.ake.ourPublicValue))
+
+ return c.serializeDHCommit(c.ake.ourPublicValue), nil
+}
+
+func (c *Conversation) serializeDHCommit(public *big.Int) []byte {
+ dhCommitMsg := dhCommit{
+ encryptedGx: c.ake.encryptedGx,
+ yhashedGx: c.version.hash2(appendMPI(nil, public)),
+ }
+ return dhCommitMsg.serialize()
+}
+
+// dhKeyMessage = alice = y
+// Alice -- DH Key --------------> Bob
+func (c *Conversation) dhKeyMessage() ([]byte, error) {
+ c.initAKE()
+
+ // TODO: where does this 40 come from?
+ y, err := c.randMPI(make([]byte, 40)[:])
+
+ if err != nil {
+ return nil, err
+ }
+
+ c.setSecretExponent(y)
+ wipeBigInt(y)
+
+ return c.serializeDHKey(), nil
+}
+
+func (c *Conversation) serializeDHKey() []byte {
+ dhKeyMsg := dhKey{
+ gy: c.ake.ourPublicValue,
+ }
+
+ return dhKeyMsg.serialize()
+}
+
+// revealSigMessage = bob = x
+// Bob ---- Reveal Signature ----> Alice
+func (c *Conversation) revealSigMessage() ([]byte, error) {
+ c.calcAKEKeys(c.calcDHSharedSecret())
+ c.ake.keys.ourKeyID++
+
+ encryptedSig, err := c.generateEncryptedSignature(&c.ake.revealKey)
+ if err != nil {
+ return nil, err
+ }
+
+ macSig := sumHMAC(c.ake.revealKey.m2, encryptedSig, c.version)
+ revealSigMsg := revealSig{
+ r: c.ake.r,
+ encryptedSig: encryptedSig,
+ macSig: macSig,
+ }
+
+ return revealSigMsg.serialize(c.version), nil
+}
+
+// sigMessage = alice = y
+// Alice -- Signature -----------> Bob
+func (c *Conversation) sigMessage() ([]byte, error) {
+ c.ake.keys.ourKeyID++
+
+ encryptedSig, err := c.generateEncryptedSignature(&c.ake.sigKey)
+ if err != nil {
+ return nil, err
+ }
+
+ macSig := sumHMAC(c.ake.sigKey.m2, encryptedSig, c.version)
+ sigMsg := sig{
+ encryptedSig: encryptedSig,
+ macSig: macSig,
+ }
+
+ return sigMsg.serialize(c.version), nil
+}
+
+// processDHCommit = alice = y
+// Bob ---- DH Commit -----------> Alice
+func (c *Conversation) processDHCommit(msg []byte) error {
+ dhCommitMsg := dhCommit{}
+ err := dhCommitMsg.deserialize(msg)
+ if err != nil {
+ return err
+ }
+
+ c.ake.encryptedGx = dhCommitMsg.encryptedGx
+ c.ake.xhashedGx = dhCommitMsg.yhashedGx
+
+ return err
+}
+
+// processDHKey = bob = x
+// Alice -- DH Key --------------> Bob
+func (c *Conversation) processDHKey(msg []byte) (isSame bool, err error) {
+ dhKeyMsg := dhKey{}
+ err = dhKeyMsg.deserialize(msg)
+ if err != nil {
+ return false, err
+ }
+
+ if !isGroupElement(dhKeyMsg.gy) {
+ return false, newOtrError("DH value out of range")
+ }
+
+ //If receive same public key twice, just retransmit the previous Reveal Signature
+ if c.ake.theirPublicValue != nil {
+ isSame = eq(c.ake.theirPublicValue, dhKeyMsg.gy)
+ return
+ }
+
+ c.ake.theirPublicValue = dhKeyMsg.gy
+ return
+}
+
+// processRevealSig = alice = y
+// Bob ---- Reveal Signature ----> Alice
+func (c *Conversation) processRevealSig(msg []byte) (err error) {
+ revealSigMsg := revealSig{}
+ err = revealSigMsg.deserialize(msg, c.version)
+ if err != nil {
+ return
+ }
+
+ r := revealSigMsg.r[:]
+ theirMAC := revealSigMsg.macSig
+ encryptedSig := revealSigMsg.encryptedSig
+
+ decryptedGx := make([]byte, len(c.ake.encryptedGx))
+ if err = decrypt(r, decryptedGx, c.ake.encryptedGx); err != nil {
+ return
+ }
+
+ if err = checkDecryptedGx(decryptedGx, c.ake.xhashedGx, c.version); err != nil {
+ return
+ }
+
+ if c.ake.theirPublicValue, err = extractGx(decryptedGx); err != nil {
+ return
+ }
+
+ c.calcAKEKeys(c.calcDHSharedSecret())
+ if err = c.processEncryptedSig(encryptedSig, theirMAC, &c.ake.revealKey); err != nil {
+ return newOtrError("in reveal signature message: " + err.Error())
+ }
+
+ return nil
+}
+
+// processSig = bob = x
+// Alice -- Signature -----------> Bob
+func (c *Conversation) processSig(msg []byte) (err error) {
+ sigMsg := sig{}
+ err = sigMsg.deserialize(msg)
+ if err != nil {
+ return
+ }
+
+ theirMAC := sigMsg.macSig
+ encryptedSig := sigMsg.encryptedSig
+
+ if err := c.processEncryptedSig(encryptedSig, theirMAC, &c.ake.sigKey); err != nil {
+ return newOtrError("in signature message: " + err.Error())
+ }
+
+ return nil
+}
+
+func (c *Conversation) checkedSignatureVerification(mb, sig []byte) error {
+ rest, ok := c.theirKey.Verify(mb, sig)
+ if !ok {
+ return newOtrError("bad signature in encrypted signature")
+ }
+
+ if len(rest) > 0 {
+ return errCorruptEncryptedSignature
+ }
+
+ return nil
+}
+
+func verifyEncryptedSignatureMAC(encryptedSig []byte, theirMAC []byte, keys *akeKeys, v otrVersion) error {
+ tomac := appendData(nil, encryptedSig)
+
+ myMAC := sumHMAC(keys.m2, tomac, v)[:v.truncateLength()]
+
+ if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 {
+ return newOtrError("bad signature MAC in encrypted signature")
+ }
+
+ return nil
+}
+
+func (c *Conversation) parseTheirKey(key []byte) (sig []byte, keyID uint32, err error) {
+ var rest []byte
+ var ok1 bool
+ rest, ok1, c.theirKey = ParsePublicKey(key)
+ sig, keyID, ok2 := extractWord(rest)
+
+ if !ok1 || !ok2 {
+ return nil, 0, errCorruptEncryptedSignature
+ }
+
+ return
+}
+
+func (c *Conversation) expectedMessageHMAC(keyID uint32, keys *akeKeys) []byte {
+ verifyData := appendAll(c.ake.theirPublicValue, c.ake.ourPublicValue, c.theirKey, keyID)
+ return sumHMAC(keys.m1, verifyData, c.version)
+}
+
+func (c *Conversation) processEncryptedSig(encryptedSig []byte, theirMAC []byte, keys *akeKeys) error {
+ if err := verifyEncryptedSignatureMAC(encryptedSig, theirMAC, keys, c.version); err != nil {
+ return err
+ }
+
+ decryptedSig := encryptedSig
+ if err := decrypt(fixedSize(c.version.keyLength(), keys.c), decryptedSig, encryptedSig); err != nil {
+ return err
+ }
+
+ sig, keyID, err := c.parseTheirKey(decryptedSig)
+ if err != nil {
+ return err
+ }
+
+ mb := c.expectedMessageHMAC(keyID, keys)
+ if err := c.checkedSignatureVerification(mb, sig); err != nil {
+ return err
+ }
+
+ c.ake.keys.theirKeyID = keyID
+
+ return nil
+}
+
+func extractGx(decryptedGx []byte) (*big.Int, error) {
+ newData, gx, ok := extractMPI(decryptedGx)
+ if !ok || len(newData) > 0 {
+ return gx, newOtrError("gx corrupt after decryption")
+ }
+
+ if !isGroupElement(gx) {
+ return gx, newOtrError("DH value out of range")
+ }
+
+ return gx, nil
+}
+
+func sumHMAC(key, data []byte, v otrVersion) []byte {
+ mac := hmac.New(v.hash2Instance, key)
+ mac.Write(data)
+ return mac.Sum(nil)
+}
+
+func checkDecryptedGx(decryptedGx, hashedGx []byte, v otrVersion) error {
+ digest := v.hash2(decryptedGx)
+
+ if subtle.ConstantTimeCompare(digest[:], hashedGx[:]) == 0 {
+ return newOtrError("bad commit MAC in reveal signature message")
+ }
+
+ return nil
+}
diff --git a/.pc/go-1.11.patch/ake_test.go b/.pc/go-1.11.patch/ake_test.go
new file mode 100644
index 0000000..b16bc2f
--- /dev/null
+++ b/.pc/go-1.11.patch/ake_test.go
@@ -0,0 +1,506 @@
+package otr3
+
+import (
+ "encoding/hex"
+ "io"
+ "math/big"
+ "testing"
+)
+
+var (
+ fixedr = bytesFromHex("abcdabcdabcdabcdabcdabcdabcdabcd")
+ expectedSharedSecret = bnFromHex("b15e9eb80f16f4beabcf7ac44c06f0b69b9f890a86a11b6cc2fd29e0f7cd15d9af7c052c4c55dfce929783e339ef094eedcfcaeb9edf896b7e201d46f16ba42dbec0a9738daa37c47a598849735b8b9ac8c98578431f8c7a6a54944ec6d830cb0ffcdf31d39cb8414bd3ddae0c483daf4e80a5990f7618edf648e68935126639d1752f49b2b8a83b170f39dd7d2a2c4ab99cb28684df2c6ee1feff9d171c25059eb6920bdf4cdab2fc0aed4aafeb66a51e938db8ca80881ad219413ecf7e0257")
+ expectedC = bytesFromHex("d942cc80b66503414c05e3752d9ba5c4")
+ expectedM1 = bytesFromHex("b6254b8eab0ad98152949454d23c8c9b08e4e9cf423b27edc09b1975a76eb59c")
+ expectedM2 = bytesFromHex("954be27015eeb0455250144d906e83e7d329c49581aea634c4189a3c981184f5")
+ alicePrivateKey = parseIntoPrivateKey("000000000080c81c2cb2eb729b7e6fd48e975a932c638b3a9055478583afa46755683e30102447f6da2d8bec9f386bbb5da6403b0040fee8650b6ab2d7f32c55ab017ae9b6aec8c324ab5844784e9a80e194830d548fb7f09a0410df2c4d5c8bc2b3e9ad484e65412be689cf0834694e0839fb2954021521ffdffb8f5c32c14dbf2020b3ce7500000014da4591d58def96de61aea7b04a8405fe1609308d000000808ddd5cb0b9d66956e3dea5a915d9aba9d8a6e7053b74dadb2fc52f9fe4e5bcc487d2305485ed95fed026ad93f06ebb8c9e8baf693b7887132c7ffdd3b0f72f4002ff4ed56583ca7c54458f8c068ca3e8a4dfa309d1dd5d34e2a4b68e6f4338835e5e0fb4317c9e4c7e4806dafda3ef459cd563775a586dd91b1319f72621bf3f00000080b8147e74d8c45e6318c37731b8b33b984a795b3653c2cd1d65cc99efe097cb7eb2fa49569bab5aab6e8a1c261a27d0f7840a5e80b317e6683042b59b6dceca2879c6ffc877a465be690c15e4a42f9a7588e79b10faac11b1ce3741fcef7aba8ce05327a2c16d279ee1b3d77eb783fb10e3356caa25635331e26dd42b8396c4d00000001420bec691fea37ecea58a5c717142f0b804452f57")
+ bobPrivateKey = parseIntoPrivateKey("000000000080a5138eb3d3eb9c1d85716faecadb718f87d31aaed1157671d7fee7e488f95e8e0ba60ad449ec732710a7dec5190f7182af2e2f98312d98497221dff160fd68033dd4f3a33b7c078d0d9f66e26847e76ca7447d4bab35486045090572863d9e4454777f24d6706f63e02548dfec2d0a620af37bbc1d24f884708a212c343b480d00000014e9c58f0ea21a5e4dfd9f44b6a9f7f6a9961a8fa9000000803c4d111aebd62d3c50c2889d420a32cdf1e98b70affcc1fcf44d59cca2eb019f6b774ef88153fb9b9615441a5fe25ea2d11b74ce922ca0232bd81b3c0fcac2a95b20cb6e6c0c5c1ace2e26f65dc43c751af0edbb10d669890e8ab6beea91410b8b2187af1a8347627a06ecea7e0f772c28aae9461301e83884860c9b656c722f0000008065af8625a555ea0e008cd04743671a3cda21162e83af045725db2eb2bb52712708dc0cc1a84c08b3649b88a966974bde27d8612c2861792ec9f08786a246fcadd6d8d3a81a32287745f309238f47618c2bd7612cb8b02d940571e0f30b96420bcd462ff542901b46109b1e5ad6423744448d20a57818a8cbb1647d0fea3b664e0000001440f9f2eb554cb00d45a5826b54bfa419b6980e48")
+)
+
+func Test_dhCommitMessage(t *testing.T) {
+ rnd := fixedRand([]string{hex.EncodeToString(fixedX().Bytes()), hex.EncodeToString(fixedr[:])})
+ c := newConversation(otrV3{}, rnd)
+
+ c.ourCurrentKey = bobPrivateKey
+
+ var out []byte
+ out = appendData(out, encryptedFixedGX())
+ out = appendData(out, hashedFixedGX())
+
+ result, err := c.dhCommitMessage()
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, result, out)
+}
+
+func Test_dhKeyMessage(t *testing.T) {
+ rnd := fixedRand([]string{hex.EncodeToString(fixedX().Bytes()), hex.EncodeToString(fixedr[:])})
+ c := newConversation(otrV3{}, rnd)
+
+ c.ourCurrentKey = alicePrivateKey
+ expectedGyValue := bnFromHex("075dfab5a1eab059052d0ad881c4938d52669630d61833a367155d67d03a457f619683d0fa829781e974fd24f6865e8128a9312a167b77326a87dea032fc31784d05b18b9cbafebe162ae9b5369f8b0c5911cf1be757f45f2a674be5126a714a6366c28086b3c7088911dcc4e5fb1481ad70a5237b8e4a6aff4954c2ca6df338b9f08691e4c0defe12689b37d4df30ddef2687f789fcf623c5d0cf6f09b7e5e69f481d5fd1b24a77636fb676e6d733d129eb93e81189340233044766a36eb07d")
+
+ var out []byte
+ out = appendMPI(out, expectedGyValue)
+
+ result, err := c.dhKeyMessage()
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, result, out)
+}
+
+func Test_dhKeyMessage_returnsAnErrorIfTheresNotEnoughRandomnessForAnMPI(t *testing.T) {
+ rnd := fixedRand([]string{"0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A"})
+ c := newConversation(otrV3{}, rnd)
+ _, err := c.dhKeyMessage()
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_revealSigMessage(t *testing.T) {
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ c := newConversation(otrV3{}, rnd)
+
+ c.ourCurrentKey = bobPrivateKey
+ c.initAKE()
+ copy(c.ake.r[:], fixedr)
+ c.setSecretExponent(fixedX())
+ c.ake.theirPublicValue = fixedGY()
+ expectedEncryptedSignature := bytesFromHex("000001d2dda2d4ef365711c172dad92804b201fcd2fdd6444568ebf0844019fb65ca4f5f57031936f9a339e08bfd4410905ab86c5d6f73e6c94de6a207f373beff3f7676faee7b1d3be21e630fe42e95db9d4ac559252bff530481301b590e2163b99bde8aa1b07448bf7252588e317b0ba2fc52f85a72a921ba757785b949e5e682341d98800aa180aa0bd01f51180d48260e4358ffae72a97f652f02eb6ae3bc6a25a317d0ca5ed0164a992240baac8e043f848332d22c10a46d12c745dc7b1b0ee37fd14614d4b69d500b8ce562040e3a4bfdd1074e2312d3e3e4c68bd15d70166855d8141f695b21c98c6055a5edb9a233925cf492218342450b806e58b3a821e5d1d2b9c6b9cbcba263908d7190a3428ace92572c064a328f86fa5b8ad2a9c76d5b9dcaeae5327f545b973795f7c655248141c2f82db0a2045e95c1936b726d6474f50283289e92ab5c7297081a54b9e70fce87603506dedd6734bab3c1567ee483cd4bcb0e669d9d97866ca274f178841dafc2acfdcd10cb0e2d07db244ff4b1d23afe253831f142083d912a7164a3425f82c95675298cf3c5eb3e096bbc95e44ecffafbb585738723c0adbe11f16c311a6cddde630b9c304717ce5b09247d482f32709ea71ced16ba930a554f9949c1acbecf")
+ expedctedMACSignature := bytesFromHex("8e6e5ef63a4e8d6aa2cfb1c5fe1831498862f69d7de32af4f9895180e4b494e6")
+
+ var out []byte
+ out = appendData(out, c.ake.r[:])
+ out = append(out, expectedEncryptedSignature...)
+ out = append(out, expedctedMACSignature[:20]...)
+
+ result, err := c.revealSigMessage()
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, result, out)
+}
+
+func Test_revealSigMessage_increasesOurKeyId(t *testing.T) {
+ var ourKeyID uint32 = 1
+ c := newConversation(otrV3{}, fixtureRand())
+ c.ourCurrentKey = bobPrivateKey
+ c.initAKE()
+ c.setSecretExponent(fixedX())
+ c.ake.theirPublicValue = fixedGY()
+ c.ake.keys.ourKeyID = ourKeyID
+
+ _, err := c.revealSigMessage()
+ assertEquals(t, err, nil)
+ assertEquals(t, c.ake.keys.ourKeyID, ourKeyID+1)
+}
+
+func Test_processDHKey(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ c.initAKE()
+ c.ake.theirPublicValue = fixedGY()
+
+ msg := appendMPI(nil, c.ake.theirPublicValue)
+
+ isSame, err := c.processDHKey(msg)
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, isSame, true)
+}
+
+func Test_processDHKeyNotSame(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ c.initAKE()
+ c.ake.theirPublicValue = fixedGY()
+
+ msg := appendMPI(nil, fixedGX())
+
+ isSame, err := c.processDHKey(msg)
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, isSame, false)
+}
+
+func Test_processDHKeyHavingError(t *testing.T) {
+ invalidGy := bnFromHex("751234566dfab5a1eab059052d0ad881c4938d52669630d61833a367155d67d03a457f619683d0fa829781e974fd24f6865e8128a9312a167b77326a87dea032fc31784d05b18b9cbafebe162ae9b5369f8b0c5911cf1be757f45f2a674be5126a714a6366c28086b3c7088911dcc4e5fb1481ad70a5237b8e4a6aff4954c2ca6df338b9f08691e4c0defe12689b37d4df30ddef2687f789fcf623c5d0cf6f09b7e5e69f481d5fd1b24a77636fb676e6d733d129eb93e81189340233044766a36eb07d")
+
+ c := newConversation(otrV2{}, fixtureRand())
+ c.initAKE()
+ c.ake.theirPublicValue = fixedGY()
+
+ msg := appendMPI(nil, invalidGy)
+
+ isSame, err := c.processDHKey(msg)
+ assertEquals(t, err.Error(), "otr: DH value out of range")
+ assertDeepEquals(t, isSame, false)
+}
+
+func Test_processEncryptedSig(t *testing.T) {
+ rnd := fixedRand([]string{})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+ c.ake.keys.ourKeyID = 1
+ c.calcAKEKeys(c.calcDHSharedSecret())
+
+ _, encryptedSig, _ := extractData(bytesFromHex("000001d2dda2d4ef365711c172dad92804b201fcd2fdd6444568ebf0844019fb65ca4f5f57031936f9a339e08bfd4410905ab86c5d6f73e6c94de6a207f373beff3f7676faee7b1d3be21e630fe42e95db9d4ac559252bff530481301b590e2163b99bde8aa1b07448bf7252588e317b0ba2fc52f85a72a921ba757785b949e5e682341d98800aa180aa0bd01f51180d48260e4358ffae72a97f652f02eb6ae3bc6a25a317d0ca5ed0164a992240baac8e043f848332d22c10a46d12c745dc7b1b0ee37fd14614d4b69d500b8ce562040e3a4bfdd1074e2312d3e3e4c68bd15d70166855d8141f695b21c98c6055a5edb9a233925cf492218342450b806e58b3a821e5d1d2b9c6b9cbcba263908d7190a3428ace92572c064a328f86fa5b8ad2a9c76d5b9dcaeae5327f545b973795f7c655248141c2f82db0a2045e95c1936b726d6474f50283289e92ab5c7297081a54b9e70fce87603506dedd6734bab3c1567ee483cd4bcb0e669d9d97866ca274f178841dafc2acfdcd10cb0e2d07db244ff4b1d23afe253831f142083d912a7164a3425f82c95675298cf3c5eb3e096bbc95e44ecffafbb585738723c0adbe11f16c311a6cddde630b9c304717ce5b09247d482f32709ea71ced16ba930a554f9949c1acbecf"))
+ macSignature := bytesFromHex("8e6e5ef63a4e8d6aa2cfb1c5fe1831498862f69d7de32af4f9895180e4b494e6")
+ err := c.processEncryptedSig(encryptedSig, macSignature[:20], &c.ake.revealKey)
+ assertEquals(t, err, nil)
+ assertEquals(t, c.ake.keys.theirKeyID, uint32(1))
+}
+
+func Test_processEncryptedSigWithBadSignatureMACError(t *testing.T) {
+ c := Conversation{version: otrV3{}}
+ c.initAKE()
+
+ _, encryptedSig, _ := extractData(bytesFromHex("000001b2dda2d4ef365711c172dad92804b201fcd2fdd6444568ebf0844019fb65ca4f5f57031936f9a339e08bfd4410905ab86c5d6f73e6c94de6a207f373beff3f7676faee7b1d3be21e630fe42e95db9d4ac559252bff530481301b590e2163b99bde8aa1b07448bf7252588e317b0ba2fc52f85a72a921ba757785b949e5e682341d98800aa180aa0bd01f51180d48260e4358ffae72a97f652f02eb6ae3bc6a25a317d0ca5ed0164a992240baac8e043f848332d22c10a46d12c745dc7b1b0ee37fd14614d4b69d500b8ce562040e3a4bfdd1074e2312d3e3e4c68bd15d70166855d8141f695b21c98c6055a5edb9a233925cf492218342450b806e58b3a821e5d1d2b9c6b9cbcba263908d7190a3428ace92572c064a328f86fa5b8ad2a9c76d5b9dcaeae5327f545b973795f7c655248141c2f82db0a2045e95c1936b726d6474f50283289e92ab5c7297081a54b9e70fce87603506dedd6734bab3c1567ee483cd4bcb0e669d9d97866ca274f178841dafc2acfdcd10cb0e2d07db244ff4b1d23afe253831f142083d912a7164a3425f82c95675298cf3c5eb3e096bbc95e44ecffafbb585738723c0adbe11f16c311a6cddde630b9c304717ce5b09247d482f32709ea71ced16ba930a554f9949c1acbecf"))
+ macSignature := bytesFromHex("8e6e5ef63a4e8d6aa2cfb1c5fe1831498862f69d7de32af4f9895180e4b494e6")
+ err := c.processEncryptedSig(encryptedSig, macSignature[:20], &c.ake.revealKey)
+ assertEquals(t, err.Error(), "otr: bad signature MAC in encrypted signature")
+ assertEquals(t, c.ake.keys.theirKeyID, uint32(0))
+}
+
+func Test_processEncryptedSigWithBadSignatureError(t *testing.T) {
+ rnd := fixedRand([]string{})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+ c.ourCurrentKey = bobPrivateKey
+ c.theirKey = bobPrivateKey.PublicKey()
+ c.setSecretExponent(fixedX())
+ c.ake.theirPublicValue = fixedGY()
+ c.ake.keys.ourKeyID = 1
+ s := c.calcDHSharedSecret()
+ c.calcAKEKeys(s)
+
+ _, encryptedSig, _ := extractData(bytesFromHex("000001d2dda2d4ef365711c172dad92804b201fcd2fdd6444568ebf0844019fb65ca4f5f57031936f9a339e08bfd4410905ab86c5d6f73e6c94de6a207f373beff3f7676faee7b1d3be21e630fe42e95db9d4ac559252bff530481301b590e2163b99bde8aa1b07448bf7252588e317b0ba2fc52f85a72a921ba757785b949e5e682341d98800aa180aa0bd01f51180d48260e4358ffae72a97f652f02eb6ae3bc6a25a317d0ca5ed0164a992240baac8e043f848332d22c10a46d12c745dc7b1b0ee37fd14614d4b69d500b8ce562040e3a4bfdd1074e2312d3e3e4c68bd15d70166855d8141f695b21c98c6055a5edb9a233925cf492218342450b806e58b3a821e5d1d2b9c6b9cbcba263908d7190a3428ace92572c064a328f86fa5b8ad2a9c76d5b9dcaeae5327f545b973795f7c655248141c2f82db0a2045e95c1936b726d6474f50283289e92ab5c7297081a54b9e70fce87603506dedd6734bab3c1567ee483cd4bcb0e669d9d97866ca274f178841dafc2acfdcd10cb0e2d07db244ff4b1d23afe253831f142083d912a7164a3425f82c95675298cf3c5eb3e096bbc95e44ecffafbb585738723c0adbe11f16c311a6cddde630b9c304717ce5b09247d482f32709ea71ced16ba930a554f9949c1acbeca"))
+ macSignature := bytesFromHex("741f14776485e6c593928fd859afe1ab4896f1e6")
+ err := c.processEncryptedSig(encryptedSig, macSignature[:20], &c.ake.revealKey)
+ assertEquals(t, err.Error(), "otr: bad signature in encrypted signature")
+ assertEquals(t, c.ake.keys.theirKeyID, uint32(0))
+}
+
+func Test_processRevealSig(t *testing.T) {
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ bob := newConversation(otrV3{}, rnd)
+ bob.initAKE()
+ alice := newConversation(otrV3{}, rnd)
+ alice.initAKE()
+
+ bob.ourCurrentKey = bobPrivateKey
+ copy(bob.ake.r[:], fixedr)
+ bob.setSecretExponent(fixedX())
+ bob.ake.theirPublicValue = fixedGY()
+ msg, err := bob.revealSigMessage()
+
+ alice.setSecretExponent(fixedY())
+ alice.ake.encryptedGx = bytesFromHex("5dd6a5999be73a99b80bdb78194a125f3067bd79e69c648b76a068117a8c4d0f36f275305423a933541937145d85ab4618094cbafbe4db0c0081614c1ff0f516c3dc4f352e9c92f88e4883166f12324d82240a8f32874c3d6bc35acedb8d501aa0111937a4859f33aa9b43ec342d78c3a45a5939c1e58e6b4f02725c1922f3df8754d1e1ab7648f558e9043ad118e63603b3ba2d8cbfea99a481835e42e73e6cd6019840f4470b606e168b1cd4a1f401c3dc52525d79fa6b959a80d4e11f1ec3a7984cf9")
+ alice.ake.xhashedGx = bytesFromHex("a3f2c4b9e3a7d1f565157ae7b0e71c721d59d3c79d39e5e4e8d08cb8464ff857")
+ err = alice.processRevealSig(msg)
+
+ assertEquals(t, err, nil)
+ assertEquals(t, alice.ake.keys.theirKeyID, uint32(1))
+ assertEquals(t, bob.ake.keys.ourKeyID, uint32(1))
+}
+
+func Test_processSig(t *testing.T) {
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ alice := newConversation(otrV3{}, rnd)
+ alice.initAKE()
+ alice.ourCurrentKey = bobPrivateKey
+ alice.setSecretExponent(fixedY())
+ alice.ake.theirPublicValue = fixedGX()
+ msg, _ := alice.sigMessage()
+
+ bob := newConversation(otrV3{}, rnd)
+ bob.initAKE()
+ bob.ake.sigKey = alice.ake.sigKey
+ bob.ourCurrentKey = alicePrivateKey
+ bob.setSecretExponent(fixedX())
+ bob.ake.theirPublicValue = fixedGY()
+
+ err := bob.processSig(msg)
+
+ assertEquals(t, err, nil)
+ assertEquals(t, alice.ake.keys.ourKeyID, uint32(1))
+ assertEquals(t, bob.ake.keys.theirKeyID, uint32(1))
+}
+
+func Test_processSig_returnsErrorIfTheSignatureDataIsInvalid(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ err := c.processSig([]byte{0x01, 0x01, 0x00})
+ assertDeepEquals(t, err, newOtrError("corrupt signature message"))
+}
+func Test_processRevealSig_returnsErrorIfTheRDataIsInvalid(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ err := c.processRevealSig([]byte{0x01, 0x01, 0x00})
+ assertDeepEquals(t, err, newOtrError("corrupt reveal signature message"))
+}
+
+func Test_processRevealSig_returnsErrorIfTheSignatureDataIsInvalid(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ err := c.processRevealSig([]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01})
+ assertDeepEquals(t, err, newOtrError("corrupt reveal signature message"))
+}
+
+func Test_sigMessage(t *testing.T) {
+ rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = alicePrivateKey
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+
+ expectedEncryptedSignature, _ := hex.DecodeString("000001d2b4f6ac650cc1d28f61a3b9bdf3cd60e2d1ea55d4c56e9f954eb22e10764861fb40d69917f5c4249fa701f3c04fae9449cd13a5054861f95fbc5775fc3cfd931cf5cc1a89eac82e7209b607c4fbf18df945e23bd0e91365fcc6c5dac072703dd8e2287372107f6a2cbb9139f5e82108d4cbcc1c6cdfcc772014136e756338745e2210d42c6e3ec4e9cf87fa8ebd8190e00f3a54bec86ee06cb7664059bb0fa79529e9d2e563ffecc5561477b3ba6bbf4ac679624b6da69a85822ed5c6ceb56a98740b1002026c503c39badab13b5d5ec948bbb961f0c90e68894a1fb70645a8e21ffe6b78e2e4ee62a62c48bd54e3d27c1166d098791518b53a10c409b5e55d16555b721a7750b7084e8972540bf0f1d76602e9b5fd58f94ed2dbf69fafccef84fdca2f9d800346b2358a200db060d8cf1b984a5213d02f7c27e452ad1cd893b0a668aaf6733809c31a392fc6cfc754691aca9a51582b636b92ea10abd661dd88bfd4c5f19b3ce265951728637b23fff7f7c0638721b6a01b3f1c3e923c10ea37d4e240fd973647d34dde6991cc3a04ce459c23e3ee2a858912ff78f405bbd9951935a120017904537db50f6e9e29338938f2b45ed323fc508d02fd0a0703e53ffc1889bccdec87e7c3d87e442fe29a7654d1")
+ expedctedMACSignature, _ := hex.DecodeString("66b47e29be91a7cf4803d731921482fd514b4a53a9dd1639b17705c90185f91d")
+
+ var out []byte
+ out = append(out, expectedEncryptedSignature...)
+ out = append(out, expedctedMACSignature[:20]...)
+
+ c.calcAKEKeys(c.calcDHSharedSecret())
+ result, err := c.sigMessage()
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, result, out)
+}
+
+func Test_sigMessage_increasesOurKeyId(t *testing.T) {
+ var ourKeyID uint32 = 1
+ c := newConversation(otrV3{}, fixtureRand())
+ c.initAKE()
+
+ c.ourCurrentKey = alicePrivateKey
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+ c.ake.keys.ourKeyID = ourKeyID
+
+ _, err := c.sigMessage()
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, c.ake.keys.ourKeyID, ourKeyID+1)
+}
+
+func Test_encrypt(t *testing.T) {
+ rnd := fixedRand([]string{hex.EncodeToString(fixedX().Bytes())})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ake.theirPublicValue = fixedGX()
+ io.ReadFull(c.rand(), c.ake.r[:])
+
+ encryptedGx, err := encrypt(c.ake.r[:], appendMPI(nil, c.ake.theirPublicValue))
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, len(encryptedGx), len(appendMPI([]byte{}, c.ake.theirPublicValue)))
+}
+
+func Test_decrypt(t *testing.T) {
+ rnd := fixedRand([]string{hex.EncodeToString(fixedX().Bytes())})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ake.theirPublicValue = fixedGX()
+ io.ReadFull(c.rand(), c.ake.r[:])
+
+ encryptedGx, _ := encrypt(c.ake.r[:], appendMPI(nil, c.ake.theirPublicValue))
+ decryptedGx := encryptedGx
+ err := decrypt(c.ake.r[:], decryptedGx, encryptedGx)
+
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, decryptedGx, appendMPI([]byte{}, c.ake.theirPublicValue))
+}
+
+func Test_checkDecryptedGxWithoutError(t *testing.T) {
+ hashedGx := otrV3{}.hash2(appendMPI([]byte{}, fixedGX()))
+ err := checkDecryptedGx(appendMPI([]byte{}, fixedGX()), hashedGx[:], otrV3{})
+ assertDeepEquals(t, err, nil)
+}
+
+func Test_checkDecryptedGxWithError(t *testing.T) {
+ hashedGx := otrV3{}.hash2(appendMPI([]byte{}, fixedGY()))
+ err := checkDecryptedGx(appendMPI([]byte{}, fixedGX()), hashedGx[:], otrV3{})
+ assertDeepEquals(t, err.Error(), "otr: bad commit MAC in reveal signature message")
+}
+
+func Test_extractGxWithoutError(t *testing.T) {
+ gx, err := extractGx(appendMPI([]byte{}, fixedGX()))
+ assertDeepEquals(t, err, nil)
+ assertDeepEquals(t, gx, fixedGX())
+}
+
+func Test_extractGxWithCorruptError(t *testing.T) {
+ gx, err := extractGx(appendMPI(appendMPI([]byte{}, fixedGX()), fixedY()))
+ assertDeepEquals(t, err.Error(), "otr: gx corrupt after decryption")
+ assertDeepEquals(t, gx, fixedGX())
+}
+
+func Test_extractGx_returnsErrorWhenThereIsNotEnoughLengthForTheMPI(t *testing.T) {
+ _, err := extractGx([]byte{0x00, 0x00, 0x00, 0x02, 0x01})
+ assertDeepEquals(t, err, newOtrError("gx corrupt after decryption"))
+}
+
+func Test_extractGxWithRangeError(t *testing.T) {
+ gx, err := extractGx(appendMPI([]byte{}, big.NewInt(1)))
+ assertDeepEquals(t, gx, big.NewInt(1))
+ assertDeepEquals(t, err.Error(), "otr: DH value out of range")
+}
+
+func Test_calcDHSharedSecret(t *testing.T) {
+ var bob Conversation
+ bob.initAKE()
+ bob.setSecretExponent(fixedX())
+ bob.ake.theirPublicValue = fixedGY()
+
+ sharedSecretB := bob.calcDHSharedSecret()
+ assertDeepEquals(t, sharedSecretB, expectedSharedSecret)
+
+ var alice Conversation
+ alice.initAKE()
+ alice.setSecretExponent(fixedY())
+ alice.ake.theirPublicValue = fixedGX()
+
+ sharedSecretA := alice.calcDHSharedSecret()
+
+ assertDeepEquals(t, sharedSecretA, expectedSharedSecret)
+}
+
+func Test_calcAKEKeys(t *testing.T) {
+ var bob Conversation
+ bob.version = otrV3{}
+ bob.initAKE()
+ bob.calcAKEKeys(expectedSharedSecret)
+
+ assertDeepEquals(t, bob.ssid[:], bytesFromHex("9cee5d2c7edbc86d"))
+ assertDeepEquals(t, bob.ake.revealKey.c, bytesFromHex("5745340b350364a02a0ac1467a318dcc"))
+ assertDeepEquals(t, bob.ake.sigKey.c, bytesFromHex("d942cc80b66503414c05e3752d9ba5c4"))
+ assertDeepEquals(t, bob.ake.revealKey.m1, bytesFromHex("d3251498fb9d977d07392a96eafb8c048d6bc67064bd7da72aa38f20f87a2e3d"))
+ assertDeepEquals(t, bob.ake.revealKey.m2, bytesFromHex("79c101a78a6c5819547a36b4813c84a8ac553d27a5d4b58be45dd0f3a67d3ca6"))
+ assertDeepEquals(t, bob.ake.sigKey.m1, bytesFromHex("b6254b8eab0ad98152949454d23c8c9b08e4e9cf423b27edc09b1975a76eb59c"))
+ assertDeepEquals(t, bob.ake.sigKey.m2, bytesFromHex("954be27015eeb0455250144d906e83e7d329c49581aea634c4189a3c981184f5"))
+}
+
+func Test_generateRevealKeyEncryptedSignature(t *testing.T) {
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = bobPrivateKey
+ c.setSecretExponent(fixedX())
+ c.ake.theirPublicValue = fixedGY()
+ c.ake.keys.ourKeyID = 1
+
+ key := c.calcDHSharedSecret()
+ c.calcAKEKeys(key)
+ expectedEncryptedSignature, _ := hex.DecodeString("000001d2dda2d4ef365711c172dad92804b201fcd2fdd6444568ebf0844019fb65ca4f5f57031936f9a339e08bfd4410905ab86c5d6f73e6c94de6a207f373beff3f7676faee7b1d3be21e630fe42e95db9d4ac559252bff530481301b590e2163b99bde8aa1b07448bf7252588e317b0ba2fc52f85a72a921ba757785b949e5e682341d98800aa180aa0bd01f51180d48260e4358ffae72a97f652f02eb6ae3bc6a25a317d0ca5ed0164a992240baac8e043f848332d22c10a46d12c745dc7b1b0ee37fd14614d4b69d500b8ce562040e3a4bfdd1074e2312d3e3e4c68bd15d70166855d8141f695b21c98c6055a5edb9a233925cf492218342450b806e58b3a821e5d1d2b9c6b9cbcba263908d7190a3428ace92572c064a328f86fa5b8ad2a9c76d5b9dcaeae5327f545b973795f7c655248141c2f82db0a2045e95c1936b726d6474f50283289e92ab5c7297081a54b9e70fce87603506dedd6734bab3c1567ee483cd4bcb0e669d9d97866ca274f178841dafc2acfdcd10cb0e2d07db244ff4b1d23afe253831f142083d912a7164a3425f82c95675298cf3c5eb3e096bbc95e44ecffafbb585738723c0adbe11f16c311a6cddde630b9c304717ce5b09247d482f32709ea71ced16ba930a554f9949c1acbecf")
+ expedctedMACSignature, _ := hex.DecodeString("8e6e5ef63a4e8d6aa2cfb1c5fe1831498862f69d7de32af4f9895180e4b494e6")
+
+ encryptedSig, err := c.generateEncryptedSignature(&c.ake.revealKey)
+ macSig := sumHMAC(c.ake.revealKey.m2, encryptedSig, otrV3{})
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, encryptedSig, expectedEncryptedSignature)
+ assertDeepEquals(t, macSig, expedctedMACSignature)
+}
+
+func Test_generateSigKeyEncryptedSignature(t *testing.T) {
+ rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = alicePrivateKey
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+ c.ake.keys.ourKeyID = 1
+
+ key := c.calcDHSharedSecret()
+ c.calcAKEKeys(key)
+ expectedEncryptedSignature, _ := hex.DecodeString("000001d2b4f6ac650cc1d28f61a3b9bdf3cd60e2d1ea55d4c56e9f954eb22e10764861fb40d69917f5c4249fa701f3c04fae9449cd13a5054861f95fbc5775fc3cfd931cf5cc1a89eac82e7209b607c4fbf18df945e23bd0e91365fcc6c5dac072703dd8e2287372107f6a2cbb9139f5e82108d4cbcc1c6cdfcc772014136e756338745e2210d42c6e3ec4e9cf87fa8ebd8190e00f3a54bec86ee06cb7664059bb0fa79529e9d2e563ffecc5561477b3ba6bbf4ac679624b6da69a85822ed5c6ceb56a98740b1002026c503c39badab13b5d5ec948bbb961f0c90e68894a1fb70645a8e21ffe6b78e2e4ee62a62c48bd54e3d27c1166d098791518b53a10c409b5e55d16555b721a7750b7084e8972540bf0f1d76602e9b5fd58f94ed2dbf69fafccef84fdca2f9d800346b2358a200db060d8cf1b984a5213d02f7c27e452ad1cd893b0a668aaf6733809c31a392fc6cfc754691aca9a51582b636b92ea10abd661dd88bfd4c5f19b3ce265951728637b23fff7f7c0638721b6a01b3f1c3e923c10ea37d4e240fd973647d34dde6991cc3a04ce459c23e3ee2a858912ff78f405bbd9951935a120017904537db50f6e9e29338938f2b45ed323fc508d02fd0a0703e53ffc1889bccdec87e7c3d87e442fe29a7654d1")
+ expedctedMACSignature, _ := hex.DecodeString("66b47e29be91a7cf4803d731921482fd514b4a53a9dd1639b17705c90185f91d")
+
+ encryptedSig, err := c.generateEncryptedSignature(&c.ake.sigKey)
+ macSig := sumHMAC(c.ake.sigKey.m2, encryptedSig, otrV3{})
+ assertEquals(t, err, nil)
+ assertDeepEquals(t, encryptedSig, expectedEncryptedSignature)
+ assertDeepEquals(t, macSig, expedctedMACSignature)
+}
+
+func Test_processDHCommit_returnsErrorIfTheEncryptedGXPartIsNotCorrect(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ err := c.processDHCommit([]byte{0x00, 0x00, 0x00, 0x02, 0x01})
+ assertDeepEquals(t, err, newOtrError("corrupt DH commit message"))
+}
+
+func Test_processDHCommit_returnsErrorIfTheHashedGXPartIsNotCorrect(t *testing.T) {
+ c := newConversation(otrV2{}, fixtureRand())
+ err := c.processDHCommit([]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01})
+ assertDeepEquals(t, err, newOtrError("corrupt DH commit message"))
+}
+
+func Test_calcXBb_returnsErrorIfTheSigningDoesntWork(t *testing.T) {
+ c := newConversation(otrV2{}, fixedRand([]string{"AB"}))
+ c.ourCurrentKey = bobPrivateKey
+ c.ake.keys.ourKeyID = 1
+
+ _, err := c.calcXb(nil, []byte{0x00})
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_dhCommitMessage_returnsErrorIfNoRandomnessIsAvailable(t *testing.T) {
+ rnd := fixedRand([]string{"ABCD"})
+ c := newConversation(otrV3{}, rnd)
+ _, err := c.dhCommitMessage()
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_dhCommitMessage_returnsErrorIfNoRandomnessIsAvailableForR(t *testing.T) {
+ rnd := fixedRand([]string{
+ "ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD",
+ "ABCDABCDABCDABCDABCDABCDABCDAB",
+ })
+ c := newConversation(otrV3{}, rnd)
+ _, err := c.dhCommitMessage()
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_generateEncryptedSignature_returnsErrorIfCalcXbFails(t *testing.T) {
+ rnd := fixedRand([]string{"abcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = bobPrivateKey
+ c.ake.theirPublicValue = fixedGX()
+ c.ake.ourPublicValue = fixedGY()
+
+ _, err := c.generateEncryptedSignature(&c.ake.revealKey)
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_revealSigMessage_returnsErrorFromGenerateEncryptedSignature(t *testing.T) {
+ rnd := fixedRand([]string{"abcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = bobPrivateKey
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+
+ _, err := c.revealSigMessage()
+ assertDeepEquals(t, err, errShortRandomRead)
+}
+
+func Test_sigMessage_returnsErrorFromgenerateEncryptedSignature(t *testing.T) {
+ rnd := fixedRand([]string{"cbcd"})
+ c := newConversation(otrV3{}, rnd)
+ c.initAKE()
+
+ c.ourCurrentKey = bobPrivateKey
+ c.setSecretExponent(fixedY())
+ c.ake.theirPublicValue = fixedGX()
+ c.ake.keys.ourKeyID = 1
+ _, err := c.sigMessage()
+ assertEquals(t, err, errShortRandomRead)
+}
+
+func Test_processDHKey_returnsErrorIfTheMessageHasAnIncorrectGyParameter(t *testing.T) {
+ c := newConversation(otrV2{}, fixedRand([]string{}))
+ _, err := c.processDHKey([]byte{0x00, 0x00, 0x00, 0x02, 0x01})
+ assertDeepEquals(t, err, newOtrError("corrupt DH key message"))
+}
+
+func Test_processDHKey_returnsErrorIfGyIsNotAValidDHParameter(t *testing.T) {
+ c := newConversation(otrV2{}, fixedRand([]string{}))
+ _, err := c.processDHKey([]byte{0x00, 0x00, 0x00, 0x01, 0x01})
+ assertDeepEquals(t, err, newOtrError("DH value out of range"))
+}
diff --git a/.pc/test_location.patch/keys_test.go b/.pc/test_location.patch/keys_test.go
new file mode 100644
index 0000000..04c8eaf
--- /dev/null
+++ b/.pc/test_location.patch/keys_test.go
@@ -0,0 +1,1082 @@
+package otr3
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/rand"
+ "os"
+ "syscall"
+ "testing"
+)
+
+var (
+ serializedPublicKey = []byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ }
+ serializedPrivateKey = []byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+
+ // len of x MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // y MPI
+ 0x14, 0xD0, 0x34, 0x5A, 0x35, 0x62, 0xC4, 0x80, 0xA0, 0x39, 0xE3, 0xC7, 0x27, 0x64, 0xF7, 0x2D, 0x79, 0x04, 0x32, 0x16,
+ }
+)
+
+func inp(s string) *bufio.Reader {
+ return bufio.NewReader(bytes.NewBuffer([]byte(s)))
+}
+
+func Test_readParameter_willReturnTheParameterRead(t *testing.T) {
+ tag, value, _, _ := readParameter(inp(`(p #00FC07ABCF0DC916AFF6E9A0D450A9B7A857#)`))
+ assertDeepEquals(t, tag, "p")
+ assertDeepEquals(t, value, bnFromHex("00FC07ABCF0DC916AFF6E9A0D450A9B7A857"))
+}
+
+func Test_readParameter_willReturnAnotherParameterRead(t *testing.T) {
+ tag, value, _, _ := readParameter(inp(`(quux #00FC07ABCF0DC916AFF6E9A0D450A9B7A858#)`))
+ assertDeepEquals(t, tag, "quux")
+ assertDeepEquals(t, value, bnFromHex("00FC07ABCF0DC916AFF6E9A0D450A9B7A858"))
+}
+
+func Test_readParameter_willReturnNotOKIfAskedToParseATooShortList(t *testing.T) {
+ _, _, _, ok := readParameter(inp(`()`))
+ assertDeepEquals(t, ok, false)
+
+ _, _, _, ok = readParameter(inp(`(quux)`))
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readParameter_willReturnNotOKIfAskedToParseSomethingOfTheWrongType(t *testing.T) {
+ _, _, _, ok := readParameter(inp(`("quux" #00FC07ABCF0DC916AFF6E9A0D450A9B7A858#)`))
+ assertDeepEquals(t, ok, false)
+
+ _, _, _, ok = readParameter(inp(`(quux "00FC07ABCF0DC916AFF6E9A0D450A9B7A858")`))
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnADSAPrivateKey(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ )`)
+ k, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, k.P, bnFromHex("00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857"))
+ assertDeepEquals(t, k.Q, bnFromHex("00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081"))
+ assertDeepEquals(t, k.G, bnFromHex("535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26"))
+ assertDeepEquals(t, k.X, bnFromHex("14D0345A3562C480A039E3C72764F72D79043216"))
+ assertDeepEquals(t, k.Y, bnFromHex("0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKForNoList(t *testing.T) {
+ from := inp(`dsa`)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKForListWithNoEntries(t *testing.T) {
+ from := inp(`()`)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKForListWithNoEnding(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKForListWithTheWrongTag(t *testing.T) {
+ from := inp(`(dsax
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKForListWithInvalidTypeOfTag(t *testing.T) {
+ from := inp(`("dsa"
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKWhenPParameterIsInvalid(t *testing.T) {
+ from := inp(`(dsa
+ (px #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#))
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKWhenQParameterIsInvalid(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (qx #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#))
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKWhenGParameterIsInvalid(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (gx #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#))
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKWhenYParameterIsInvalid(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (yx #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#))
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readDSAPrivateKey_willReturnNotOKWhenXParameterIsInvalid(t *testing.T) {
+ from := inp(`(dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (xx #14D0345A3562C480A039E3C72764F72D79043216#))
+ `)
+ _, ok := readDSAPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnAPrivateKey(t *testing.T) {
+ from := inp(`(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ k, ok := readPrivateKey(from)
+ assertDeepEquals(t, k.(*DSAPrivateKey).PrivateKey.P, bnFromHex("00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857"))
+ assertDeepEquals(t, k.(*DSAPrivateKey).PrivateKey.Q, bnFromHex("00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081"))
+ assertDeepEquals(t, k.(*DSAPrivateKey).PrivateKey.G, bnFromHex("535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26"))
+ assertDeepEquals(t, k.(*DSAPrivateKey).PrivateKey.X, bnFromHex("14D0345A3562C480A039E3C72764F72D79043217"))
+ assertDeepEquals(t, k.(*DSAPrivateKey).PrivateKey.Y, bnFromHex("0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readPrivateKey_willReturnNotOKForSomethingNotAList(t *testing.T) {
+ from := inp(`one`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnNotOKForAListThatIsNotEnded(t *testing.T) {
+ from := inp(`(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnNotOKForAnInvalidDSAKey(t *testing.T) {
+ from := inp(`(private-key (dsax
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnNotOKForAnInvalidTag(t *testing.T) {
+ from := inp(`(private-keyx (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnNotOKForATagOfWrongType(t *testing.T) {
+ from := inp(`("private-key" (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readPrivateKey_willReturnNotOKForNoTag(t *testing.T) {
+ from := inp(`("private-key" (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ _, ok := readPrivateKey(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnAnAccount(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(protocol libpurple-Jabber)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ )))`)
+ k, ok, _ := readAccount(from)
+ assertDeepEquals(t, k.Name, "foo")
+ assertDeepEquals(t, k.Protocol, "libpurple-Jabber")
+ assertDeepEquals(t, k.Key.(*DSAPrivateKey).PrivateKey.P, bnFromHex("00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readAccount_willReturnNotOKForSomethingNotAList(t *testing.T) {
+ from := inp(`account`)
+ _, ok, atEnd := readAccount(from)
+ assertDeepEquals(t, ok, true)
+ assertDeepEquals(t, atEnd, true)
+}
+
+func Test_readAccount_willReturnNotOKForAListThatIsNotEnded(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(protocol libpurple-Jabber)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ ))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAMissingName(t *testing.T) {
+ from := inp(`(account
+(protocol libpurple-Jabber)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAMissingProtocol(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAMissingPrivateKey(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(protocol libpurple-Jabber)
+)`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAnIncorrectName(t *testing.T) {
+ from := inp(`(account
+(namex "foo")
+(protocol libpurple-Jabber)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAnIncorrectProtocol(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(protocolx libpurple-Jabber)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccount_willReturnNotOKForAnIncorrectPrivateKey(t *testing.T) {
+ from := inp(`(account
+(name "foo")
+(protocol libpurple-Jabber)
+(private-keyx (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043217#)
+ )))`)
+ _, ok, _ := readAccount(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnTheAccountRead(t *testing.T) {
+ from := inp(`(privkeys (account
+(name "foo2")
+(protocol libpurple-Jabberx)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858#)
+ ))))`)
+ k, ok := readAccounts(from)
+ assertDeepEquals(t, k[0].Name, "foo2")
+ assertDeepEquals(t, k[0].Protocol, "libpurple-Jabberx")
+ assertDeepEquals(t, k[0].Key.(*DSAPrivateKey).PrivateKey.P, bnFromHex("00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readAccounts_willReturnZeroAccountsIfNoAccountsThere(t *testing.T) {
+ from := inp(`(privkeys)`)
+ k, ok := readAccounts(from)
+ assertDeepEquals(t, len(k), 0)
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readAccounts_willReturnNotOKForNoList(t *testing.T) {
+ from := inp(`privkeys`)
+ _, ok := readAccounts(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnNotOKForNonFinishedList(t *testing.T) {
+ from := inp(`(privkeys`)
+ _, ok := readAccounts(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnNotOKForIncorrectTag(t *testing.T) {
+ from := inp(`(privkeysx)`)
+ _, ok := readAccounts(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnNotOKForTagWithWrongType(t *testing.T) {
+ from := inp(`("privkeys")`)
+ _, ok := readAccounts(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnNotOKForAccountThatIsNotOK(t *testing.T) {
+ from := inp(`(privkeys
+(accountx
+ (name "2")
+ (protocol libpurple-jabber-gtalk)
+ (private-key
+ (dsa
+ (p #00F24843F9447B62138AE49BF83188D1353ADA5CAC118890CFDEC01BF349D75E887B19C221665C7857CAD583AF656C67FB04A99FD8F8D69D09C9529C6C14D426F1E3924DC9243AF2970E3E4B04A23489A09E8A90E7E81EBA763AD4F0636B8A43415B6FC16A02C3624CE76272FA00783C8DB850D3A996B58136F7A0EB80AE0BC613#)
+ (q #00D16B2607FCBC0EDC639F763A54F34475B1CC8473#)
+ (g #00B15AFEF5F96EFEE41006F136C23A18849DA8133069A879D083F7C7AA362E187DAE3ED0C4F372D0D4E3AAE567008A1872A6E85D8F84E53A3FE1B352AF0B4E2F0CB033A6D34285ECD3E4A93653BDE99C3A8D840D9D35F82AC2FA8539DB6C7F7A1DAD77FEECD62803757FF1E2DE4CEC4A5A2AD643271514DDEEEF3D008F66FBF9DB#)
+ (y #01F9BE7DA0E4E84774048058B53202B2704BF688A306092ED533A55E68EABA814C8D62F45AAD8FF30C3055DCA461B7DBA6B78938FC4D69780A830C6457CC107F3D275C21D00E53147C14162176C77169D3BCA586DC30F15F4B482160E276869AA336F38AF7FC3686A764AB5A02C751D921A42B8B9AE8E06918059CD73C424154#)
+ (x #00943480B228FC0D3D7ADFC91F680FC415E1306333#)
+ )
+ )
+ ))`)
+ _, ok := readAccounts(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccounts_willReturnMoreThanOneAccount(t *testing.T) {
+ from := inp(`(privkeys (account
+(name "foo2")
+(protocol libpurple-Jabberx)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858#)
+ )))
+ (account
+ (name "2")
+ (protocol libpurple-jabber-gtalk)
+ (private-key
+ (dsa
+ (p #00F24843F9447B62138AE49BF83188D1353ADA5CAC118890CFDEC01BF349D75E887B19C221665C7857CAD583AF656C67FB04A99FD8F8D69D09C9529C6C14D426F1E3924DC9243AF2970E3E4B04A23489A09E8A90E7E81EBA763AD4F0636B8A43415B6FC16A02C3624CE76272FA00783C8DB850D3A996B58136F7A0EB80AE0BC613#)
+ (q #00D16B2607FCBC0EDC639F763A54F34475B1CC8473#)
+ (g #00B15AFEF5F96EFEE41006F136C23A18849DA8133069A879D083F7C7AA362E187DAE3ED0C4F372D0D4E3AAE567008A1872A6E85D8F84E53A3FE1B352AF0B4E2F0CB033A6D34285ECD3E4A93653BDE99C3A8D840D9D35F82AC2FA8539DB6C7F7A1DAD77FEECD62803757FF1E2DE4CEC4A5A2AD643271514DDEEEF3D008F66FBF9DB#)
+ (y #01F9BE7DA0E4E84774048058B53202B2704BF688A306092ED533A55E68EABA814C8D62F45AAD8FF30C3055DCA461B7DBA6B78938FC4D69780A830C6457CC107F3D275C21D00E53147C14162176C77169D3BCA586DC30F15F4B482160E276869AA336F38AF7FC3686A764AB5A02C751D921A42B8B9AE8E06918059CD73C424154#)
+ (x #00943480B228FC0D3D7ADFC91F680FC415E1306333#)
+ )
+ )
+ )
+ )`)
+ k, ok := readAccounts(from)
+ assertDeepEquals(t, k[0].Name, "foo2")
+ assertDeepEquals(t, k[0].Protocol, "libpurple-Jabberx")
+ assertDeepEquals(t, k[0].Key.(*DSAPrivateKey).PrivateKey.P, bnFromHex("00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858"))
+ assertDeepEquals(t, k[1].Name, "2")
+ assertDeepEquals(t, k[1].Protocol, "libpurple-jabber-gtalk")
+ assertDeepEquals(t, k[1].Key.(*DSAPrivateKey).PrivateKey.Q, bnFromHex("00D16B2607FCBC0EDC639F763A54F34475B1CC8473"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_PublicKey_parse_ParsePofAPublicKeyCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse(serializedPublicKey)
+
+ assertDeepEquals(t, pk.P, bnFromHex("00F24843F9447B62138AE49BF83188D1353ADA5CAC118890CFDEC01BF349D75E887B19C221665C7857CAD583AF656C67FB04A99FD8F8D69D09C9529C6C14D426F1E3924DC9243AF2970E3E4B04A23489A09E8A90E7E81EBA763AD4F0636B8A43415B6FC16A02C3624CE76272FA00783C8DB850D3A996B58136F7A0EB80AE0BC613"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfThereIsTooLittleDataForTheKeyTypeTag(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{0x00})
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfTheTypeTagIsNotCorrect(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for something else
+ 0x00, 0x01,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfPCannotBeParsedCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x10, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfQCannotBeParsedCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x10, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfGCannotBeParsedCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x10, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfYCannotBeParsedCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x10, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ReturnsNotOKIfParametersAreMissing(t *testing.T) {
+ pk := &DSAPublicKey{}
+ _, ok := pk.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+ })
+
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_parse_ParseQofAPublicKeyCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(serializedPublicKey)
+
+ assertDeepEquals(t, pk.Q, bnFromHex("00D16B2607FCBC0EDC639F763A54F34475B1CC8473"))
+}
+
+func Test_PublicKey_parse_ParseGofAPublicKeyCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(serializedPublicKey)
+
+ assertDeepEquals(t, pk.G, bnFromHex("00B15AFEF5F96EFEE41006F136C23A18849DA8133069A879D083F7C7AA362E187DAE3ED0C4F372D0D4E3AAE567008A1872A6E85D8F84E53A3FE1B352AF0B4E2F0CB033A6D34285ECD3E4A93653BDE99C3A8D840D9D35F82AC2FA8539DB6C7F7A1DAD77FEECD62803757FF1E2DE4CEC4A5A2AD643271514DDEEEF3D008F66FBF9DB"))
+}
+
+func Test_PublicKey_parse_ParseYofAPublicKeyCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(serializedPublicKey)
+
+ assertDeepEquals(t, pk.Y, bnFromHex("01F9BE7DA0E4E84774048058B53202B2704BF688A306092ED533A55E68EABA814C8D62F45AAD8FF30C3055DCA461B7DBA6B78938FC4D69780A830C6457CC107F3D275C21D00E53147C14162176C77169D3BCA586DC30F15F4B482160E276869AA336F38AF7FC3686A764AB5A02C751D921A42B8B9AE8E06918059CD73C424154"))
+}
+
+func Test_PrivateKey_parse_ParsePublicKeyofAPrivateKeyCorrectly(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ pk := &DSAPublicKey{}
+ priv.Parse(serializedPrivateKey)
+ pk.Parse(serializedPublicKey)
+
+ assertDeepEquals(t, priv.PublicKey(), pk)
+}
+
+func Test_PrivateKey_parse_ParseXofAPrivateKeyCorrectly(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ _, ok := priv.Parse(serializedPrivateKey)
+ assertDeepEquals(t, priv.X, bnFromHex("14D0345A3562C480A039E3C72764F72D79043216"))
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_PrivateKey_parse_ReturnsNotOKIfPublicKeyIsNotOK(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ _, ok := priv.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA,
+
+ // len of x MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // x MPI
+ 0x14, 0xD0, 0x34, 0x5A, 0x35, 0x62, 0xC4, 0x80, 0xA0, 0x39, 0xE3, 0xC7, 0x27, 0x64, 0xF7, 0x2D, 0x79, 0x04, 0x32, 0x16,
+ })
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PrivateKey_parse_ReturnsNotOKIfPrivateKeyIsNotOK(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ _, ok := priv.Parse([]byte{
+ // key type for DSA
+ 0x00, 0x00,
+
+ // len of p MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // p MPI
+ 0xF2, 0x48, 0x43, 0xF9, 0x44, 0x7B, 0x62, 0x13, 0x8A, 0xE4, 0x9B, 0xF8, 0x31, 0x88, 0xD1, 0x35, 0x3A, 0xDA, 0x5C, 0xAC, 0x11, 0x88, 0x90, 0xCF, 0xDE, 0xC0, 0x1B, 0xF3, 0x49, 0xD7, 0x5E, 0x88, 0x7B, 0x19, 0xC2, 0x21, 0x66, 0x5C, 0x78, 0x57, 0xCA, 0xD5, 0x83, 0xAF, 0x65, 0x6C, 0x67, 0xFB, 0x04, 0xA9, 0x9F, 0xD8, 0xF8, 0xD6, 0x9D, 0x09, 0xC9, 0x52, 0x9C, 0x6C, 0x14, 0xD4, 0x26, 0xF1, 0xE3, 0x92, 0x4D, 0xC9, 0x24, 0x3A, 0xF2, 0x97, 0x0E, 0x3E, 0x4B, 0x04, 0xA2, 0x34, 0x89, 0xA0, 0x9E, 0x8A, 0x90, 0xE7, 0xE8, 0x1E, 0xBA, 0x76, 0x3A, 0xD4, 0xF0, 0x63, 0x6B, 0x8A, 0x43, 0x41, 0x5B, 0x6F, 0xC1, 0x6A, 0x02, 0xC3, 0x62, 0x4C, 0xE7, 0x62, 0x72, 0xFA, 0x00, 0x78, 0x3C, 0x8D, 0xB8, 0x50, 0xD3, 0xA9, 0x96, 0xB5, 0x81, 0x36, 0xF7, 0xA0, 0xEB, 0x80, 0xAE, 0x0B, 0xC6, 0x13,
+
+ // len of q MPI
+ 0x00, 0x00, 0x00, 0x14,
+ // q MPI
+ 0xD1, 0x6B, 0x26, 0x07, 0xFC, 0xBC, 0x0E, 0xDC, 0x63, 0x9F, 0x76, 0x3A, 0x54, 0xF3, 0x44, 0x75, 0xB1, 0xCC, 0x84, 0x73,
+
+ // len of g MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // g MPI
+ 0xB1, 0x5A, 0xFE, 0xF5, 0xF9, 0x6E, 0xFE, 0xE4, 0x10, 0x06, 0xF1, 0x36, 0xC2, 0x3A, 0x18, 0x84, 0x9D, 0xA8, 0x13, 0x30, 0x69, 0xA8, 0x79, 0xD0, 0x83, 0xF7, 0xC7, 0xAA, 0x36, 0x2E, 0x18, 0x7D, 0xAE, 0x3E, 0xD0, 0xC4, 0xF3, 0x72, 0xD0, 0xD4, 0xE3, 0xAA, 0xE5, 0x67, 0x00, 0x8A, 0x18, 0x72, 0xA6, 0xE8, 0x5D, 0x8F, 0x84, 0xE5, 0x3A, 0x3F, 0xE1, 0xB3, 0x52, 0xAF, 0x0B, 0x4E, 0x2F, 0x0C, 0xB0, 0x33, 0xA6, 0xD3, 0x42, 0x85, 0xEC, 0xD3, 0xE4, 0xA9, 0x36, 0x53, 0xBD, 0xE9, 0x9C, 0x3A, 0x8D, 0x84, 0x0D, 0x9D, 0x35, 0xF8, 0x2A, 0xC2, 0xFA, 0x85, 0x39, 0xDB, 0x6C, 0x7F, 0x7A, 0x1D, 0xAD, 0x77, 0xFE, 0xEC, 0xD6, 0x28, 0x03, 0x75, 0x7F, 0xF1, 0xE2, 0xDE, 0x4C, 0xEC, 0x4A, 0x5A, 0x2A, 0xD6, 0x43, 0x27, 0x15, 0x14, 0xDD, 0xEE, 0xEF, 0x3D, 0x00, 0x8F, 0x66, 0xFB, 0xF9, 0xDB,
+
+ // len of y MPI
+ 0x00, 0x00, 0x00, 0x80,
+ // y MPI
+ 0x01, 0xF9, 0xBE, 0x7D, 0xA0, 0xE4, 0xE8, 0x47, 0x74, 0x04, 0x80, 0x58, 0xB5, 0x32, 0x02, 0xB2, 0x70, 0x4B, 0xF6, 0x88, 0xA3, 0x06, 0x09, 0x2E, 0xD5, 0x33, 0xA5, 0x5E, 0x68, 0xEA, 0xBA, 0x81, 0x4C, 0x8D, 0x62, 0xF4, 0x5A, 0xAD, 0x8F, 0xF3, 0x0C, 0x30, 0x55, 0xDC, 0xA4, 0x61, 0xB7, 0xDB, 0xA6, 0xB7, 0x89, 0x38, 0xFC, 0x4D, 0x69, 0x78, 0x0A, 0x83, 0x0C, 0x64, 0x57, 0xCC, 0x10, 0x7F, 0x3D, 0x27, 0x5C, 0x21, 0xD0, 0x0E, 0x53, 0x14, 0x7C, 0x14, 0x16, 0x21, 0x76, 0xC7, 0x71, 0x69, 0xD3, 0xBC, 0xA5, 0x86, 0xDC, 0x30, 0xF1, 0x5F, 0x4B, 0x48, 0x21, 0x60, 0xE2, 0x76, 0x86, 0x9A, 0xA3, 0x36, 0xF3, 0x8A, 0xF7, 0xFC, 0x36, 0x86, 0xA7, 0x64, 0xAB, 0x5A, 0x02, 0xC7, 0x51, 0xD9, 0x21, 0xA4, 0x2B, 0x8B, 0x9A, 0xE8, 0xE0, 0x69, 0x18, 0x05, 0x9C, 0xD7, 0x3C, 0x42, 0x41, 0x54,
+
+ // len of x MPI
+ 0x00, 0x00, 0x10, 0x14,
+ // x MPI
+ 0x14, 0xD0, 0x34, 0x5A, 0x35, 0x62, 0xC4, 0x80, 0xA0, 0x39, 0xE3, 0xC7, 0x27, 0x64, 0xF7, 0x2D, 0x79, 0x04, 0x32, 0x16,
+ })
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_PublicKey_serialize_willSerializeAPublicKeyCorrectly(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(serializedPublicKey)
+ result := pk.serialize()
+ assertDeepEquals(t, result, serializedPublicKey)
+}
+
+func Test_PublicKey_serialize_returnsEmptyForNil(t *testing.T) {
+ pk := &DSAPublicKey{}
+ result := pk.serialize()
+ assertNil(t, result)
+}
+
+func Test_PrivateKey_roundTripGeneratesCorrectValue(t *testing.T) {
+ pk := &DSAPrivateKey{}
+ pk.Parse(serializedPrivateKey)
+ result := pk.serialize()
+ assertDeepEquals(t, result, serializedPrivateKey)
+}
+
+func Test_PublicKey_fingerprint_willGenerateACorrectFingerprint(t *testing.T) {
+ priv := parseIntoPrivateKey("000000000080c81c2cb2eb729b7e6fd48e975a932c638b3a9055478583afa46755683e30102447f6da2d8bec9f386bbb5da6403b0040fee8650b6ab2d7f32c55ab017ae9b6aec8c324ab5844784e9a80e194830d548fb7f09a0410df2c4d5c8bc2b3e9ad484e65412be689cf0834694e0839fb2954021521ffdffb8f5c32c14dbf2020b3ce7500000014da4591d58def96de61aea7b04a8405fe1609308d000000808ddd5cb0b9d66956e3dea5a915d9aba9d8a6e7053b74dadb2fc52f9fe4e5bcc487d2305485ed95fed026ad93f06ebb8c9e8baf693b7887132c7ffdd3b0f72f4002ff4ed56583ca7c54458f8c068ca3e8a4dfa309d1dd5d34e2a4b68e6f4338835e5e0fb4317c9e4c7e4806dafda3ef459cd563775a586dd91b1319f72621bf3f00000080b8147e74d8c45e6318c37731b8b33b984a795b3653c2cd1d65cc99efe097cb7eb2fa49569bab5aab6e8a1c261a27d0f7840a5e80b317e6683042b59b6dceca2879c6ffc877a465be690c15e4a42f9a7588e79b10faac11b1ce3741fcef7aba8ce05327a2c16d279ee1b3d77eb783fb10e3356caa25635331e26dd42b8396c4d00000001420bec691fea37ecea58a5c717142f0b804452f57")
+ expectedFingerprint := bytesFromHex("0bb01c360424522e94ee9c346ce877a1a4288b2f")
+ assertDeepEquals(t, priv.PublicKey().Fingerprint(), expectedFingerprint)
+}
+
+func Test_PublicKey_fingerprint_generatesForEmpty(t *testing.T) {
+ pk := &DSAPublicKey{}
+ result := pk.Fingerprint()
+ assertNil(t, result)
+}
+
+func Test_PublicKey_Verify_willReturnOK(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(bytesFromHex("000000000080a5138eb3d3eb9c1d85716faecadb718f87d31aaed1157671d7fee7e488f95e8e0ba60ad449ec732710a7dec5190f7182af2e2f98312d98497221dff160fd68033dd4f3a33b7c078d0d9f66e26847e76ca7447d4bab35486045090572863d9e4454777f24d6706f63e02548dfec2d0a620af37bbc1d24f884708a212c343b480d00000014e9c58f0ea21a5e4dfd9f44b6a9f7f6a9961a8fa9000000803c4d111aebd62d3c50c2889d420a32cdf1e98b70affcc1fcf44d59cca2eb019f6b774ef88153fb9b9615441a5fe25ea2d11b74ce922ca0232bd81b3c0fcac2a95b20cb6e6c0c5c1ace2e26f65dc43c751af0edbb10d669890e8ab6beea91410b8b2187af1a8347627a06ecea7e0f772c28aae9461301e83884860c9b656c722f0000008065af8625a555ea0e008cd04743671a3cda21162e83af045725db2eb2bb52712708dc0cc1a84c08b3649b88a966974bde27d8612c2861792ec9f08786a246fcadd6d8d3a81a32287745f309238f47618c2bd7612cb8b02d940571e0f30b96420bcd462ff542901b46109b1e5ad6423744448d20a57818a8cbb1647d0fea3b664e"))
+ hashed := bytesFromHex("122773a99f5eafbaaa04b419b5c417b9949ce11bf199ea1bee3586619b94bb29")
+ sig := bytesFromHex("2e9e1c92773e6e51541f47f674f17e24138c48af2c86aea3e5689bd9116b5d6d28562c0aeb84a989")
+ result, ok := pk.Verify(hashed, sig)
+ assertEquals(t, ok, true)
+ assertDeepEquals(t, result, sig[20*2:])
+}
+
+func Test_PublicKey_Verify_willReturnNotOK(t *testing.T) {
+ pk := &DSAPublicKey{}
+ pk.Parse(serializedPublicKey)
+ hashed := bytesFromHex("122773a99f5eafbaaa04b419b5c417b9949ce11bf199ea1bee3586619b94bb29")
+ sig := bytesFromHex("2e9e1c92773e6e51541f47f674f17e24138c48af2c86aea3e5689bd9116b5d6d28562c0aeb84a989")
+ result, ok := pk.Verify(hashed, sig)
+ assertEquals(t, ok, false)
+ assertDeepEquals(t, result, sig[20*2:])
+}
+
+func Test_readAccountName_willSignalNotOKIfNoListIsGiven(t *testing.T) {
+ from := inp(`name`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfNoCompleteListIsGiven(t *testing.T) {
+ from := inp(`(name "foo"`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfNoNameValueIsGiven(t *testing.T) {
+ from := inp(`(name)`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfNoTagIsGiven(t *testing.T) {
+ from := inp(`()`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfTagIsTheWrongType(t *testing.T) {
+ from := inp(`("blarg" "foo")`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfTagIsNotTheSymbolName(t *testing.T) {
+ from := inp(`(namex "foo")`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalNotOKIfValueIsTheWrongType(t *testing.T) {
+ from := inp(`(name #42)`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountName_willSignalOKIfTagAndValueIsCorrect(t *testing.T) {
+ from := inp(`(name "foo")`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readAccountName_willSignalOKIfTagAndValueAsSymbolIsCorrect(t *testing.T) {
+ from := inp(`(name foo)`)
+ _, ok := readAccountName(from)
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfNoListIsGiven(t *testing.T) {
+ from := inp(`protocol`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfNoCompleteListIsGiven(t *testing.T) {
+ from := inp(`(protocol libpurple`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfNoProtocolValueIsGiven(t *testing.T) {
+ from := inp(`(protocol)`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfNoTagIsGiven(t *testing.T) {
+ from := inp(`()`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfTagIsTheWrongType(t *testing.T) {
+ from := inp(`("protocol" libpurple)`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfTagIsNotTheSymbolProtocol(t *testing.T) {
+ from := inp(`(protocolx libpurple)`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalNotOKIfValueIsTheWrongType(t *testing.T) {
+ from := inp(`(protocol "libpurple")`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, false)
+}
+
+func Test_readAccountProtocol_willSignalOKIfTagAndValueIsCorrect(t *testing.T) {
+ from := inp(`(protocol libpurple)`)
+ _, ok := readAccountProtocol(from)
+ assertDeepEquals(t, ok, true)
+}
+
+func Test_ImportKeys_willReturnARelevantErrorForIncorrectData(t *testing.T) {
+ from := bytes.NewBuffer([]byte(`(privkeys (account
+(name "foo2")
+(protocol libpurple-Jabberx)
+(private-key (dsa
+ (px #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858#)
+ ))))`))
+ _, err := ImportKeys(from)
+ assertDeepEquals(t, err, newOtrError("couldn't import data into private key"))
+}
+
+func Test_ImportKeys_willReturnTheParsedAccountInformation(t *testing.T) {
+ from := bytes.NewBuffer([]byte(`(privkeys (account
+(name "foo2")
+(protocol libpurple-Jabberx)
+(private-key (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A858#)
+ ))))`))
+ res, err := ImportKeys(from)
+ assertDeepEquals(t, len(res), 1)
+ assertDeepEquals(t, err, nil)
+}
+
+func Test_ImportKeysFromFile_willReturnAnErrorIfAskedToReadAFileNameThatDoesntExist(t *testing.T) {
+ _, err := ImportKeysFromFile("this_file_doesnt_exist.asc")
+ assertDeepEquals(t, err, &os.PathError{
+ Op: "open",
+ Path: "this_file_doesnt_exist.asc",
+ Err: syscall.Errno(0x02)})
+}
+
+func Test_ImportKeysFromFile_willReturnAValidAccountReadFromAFile(t *testing.T) {
+ res, err := ImportKeysFromFile("test_resources/valid_key.asc")
+ assertDeepEquals(t, len(res), 1)
+ assertDeepEquals(t, err, nil)
+}
+
+func Test_ImportKeysFromFile_willReturnAnErrorIfTheFileIsinvalid(t *testing.T) {
+ _, err := ImportKeysFromFile("test_resources/invalid_key.asc")
+ assertDeepEquals(t, err, newOtrError("couldn't import data into private key"))
+}
+
+func Test_PrivateKey_ImportWithoutError(t *testing.T) {
+ const libOTRPrivateKey = `(privkeys
+ (account
+(name "foo@example.com")
+(protocol prpl-jabber)
+(private-key
+ (dsa
+ (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
+ (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
+ (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
+ (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ )
+ )
+ )
+)`
+ priv := &DSAPrivateKey{}
+ ok := priv.Import([]byte(libOTRPrivateKey))
+ assertEquals(t, ok, true)
+}
+
+func Test_PrivateKey_GenerateWithoutError(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ err := priv.Generate(rand.Reader)
+ assertEquals(t, err, nil)
+}
+
+func Test_PrivateKey_GenerateErrorWhenGenerateParams(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ err := priv.Generate(fixedRand([]string{"ABCDEF"}))
+ assertEquals(t, err.Error(), "unexpected EOF")
+}
+
+func Test_notHex(t *testing.T) {
+ var isNotHex bool
+ testString := "o0"
+ isNotHex = notHex(rune(testString[0]))
+ assertEquals(t, isNotHex, true)
+ isNotHex = notHex(rune(testString[1]))
+ assertEquals(t, isNotHex, false)
+}
+
+func Test_exportAccounts_exportsAccounts(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ priv.Parse(serializedPrivateKey)
+ acc := Account{Name: "hello", Protocol: "go-xmpp", Key: priv}
+ bt := bytes.NewBuffer(make([]byte, 0, 200))
+ exportAccounts([]*Account{&acc}, bt)
+ assertDeepEquals(t, bt.String(),
+ `(privkeys
+ (account
+ (name "hello")
+ (protocol go-xmpp)
+ (private-key
+ (dsa
+ (p #F24843F9447B62138AE49BF83188D1353ADA5CAC118890CFDEC01BF349D75E887B19C221665C7857CAD583AF656C67FB04A99FD8F8D69D09C9529C6C14D426F1E3924DC9243AF2970E3E4B04A23489A09E8A90E7E81EBA763AD4F0636B8A43415B6FC16A02C3624CE76272FA00783C8DB850D3A996B58136F7A0EB80AE0BC613#)
+ (q #D16B2607FCBC0EDC639F763A54F34475B1CC8473#)
+ (g #B15AFEF5F96EFEE41006F136C23A18849DA8133069A879D083F7C7AA362E187DAE3ED0C4F372D0D4E3AAE567008A1872A6E85D8F84E53A3FE1B352AF0B4E2F0CB033A6D34285ECD3E4A93653BDE99C3A8D840D9D35F82AC2FA8539DB6C7F7A1DAD77FEECD62803757FF1E2DE4CEC4A5A2AD643271514DDEEEF3D008F66FBF9DB#)
+ (y #1F9BE7DA0E4E84774048058B53202B2704BF688A306092ED533A55E68EABA814C8D62F45AAD8FF30C3055DCA461B7DBA6B78938FC4D69780A830C6457CC107F3D275C21D00E53147C14162176C77169D3BCA586DC30F15F4B482160E276869AA336F38AF7FC3686A764AB5A02C751D921A42B8B9AE8E06918059CD73C424154#)
+ (x #14D0345A3562C480A039E3C72764F72D79043216#)
+ )
+ )
+ )
+)
+`)
+}
+
+func Test_ExportKeysToFile_exportsKeysToAFile(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ priv.Parse(serializedPrivateKey)
+ acc := &Account{Name: "hello", Protocol: "go-xmpp", Key: priv}
+
+ err := ExportKeysToFile([]*Account{acc}, "test_resources/test_export_of_keys.blah")
+ assertNil(t, err)
+
+ res, err2 := ImportKeysFromFile("test_resources/test_export_of_keys.blah")
+
+ defer os.Remove("test_resources/test_export_of_keys.blah")
+
+ assertNil(t, err2)
+ assertDeepEquals(t, res[0].Key, acc.Key)
+}
+
+func Test_ExportKeysToFile_returnsAnErrorIfSomethingGoesWrong(t *testing.T) {
+ priv := &DSAPrivateKey{}
+ priv.Parse(serializedPrivateKey)
+ acc := &Account{Name: "hello", Protocol: "go-xmpp", Key: priv}
+
+ err := ExportKeysToFile([]*Account{acc}, "non_existing_directory/test_export_of_keys.blah")
+ assertDeepEquals(t, err.Error(), "open non_existing_directory/test_export_of_keys.blah: no such file or directory")
+}
diff --git a/ake.go b/ake.go
index ec8c367..01a220f 100644
--- a/ake.go
+++ b/ake.go
@@ -87,7 +87,7 @@ func (c *Conversation) calcXb(key *akeKeys, mb []byte) ([]byte, error) {
xb = appendWord(xb, c.ake.keys.ourKeyID)
sigb, err := c.ourCurrentKey.Sign(c.rand(), mb)
- if err == io.ErrUnexpectedEOF {
+ if err == io.ErrUnexpectedEOF || err == io.EOF {
return nil, errShortRandomRead
}
diff --git a/ake_test.go b/ake_test.go
index b16bc2f..8ea6d14 100644
--- a/ake_test.go
+++ b/ake_test.go
@@ -55,7 +55,10 @@ func Test_dhKeyMessage_returnsAnErrorIfTheresNotEnoughRandomnessForAnMPI(t *test
}
func Test_revealSigMessage(t *testing.T) {
- rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ })
c := newConversation(otrV3{}, rnd)
c.ourCurrentKey = bobPrivateKey
@@ -175,7 +178,10 @@ func Test_processEncryptedSigWithBadSignatureError(t *testing.T) {
}
func Test_processRevealSig(t *testing.T) {
- rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ })
bob := newConversation(otrV3{}, rnd)
bob.initAKE()
alice := newConversation(otrV3{}, rnd)
@@ -198,7 +204,9 @@ func Test_processRevealSig(t *testing.T) {
}
func Test_processSig(t *testing.T) {
- rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
alice := newConversation(otrV3{}, rnd)
alice.initAKE()
alice.ourCurrentKey = bobPrivateKey
@@ -238,7 +246,8 @@ func Test_processRevealSig_returnsErrorIfTheSignatureDataIsInvalid(t *testing.T)
}
func Test_sigMessage(t *testing.T) {
- rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
c := newConversation(otrV3{}, rnd)
c.initAKE()
@@ -373,7 +382,9 @@ func Test_calcAKEKeys(t *testing.T) {
}
func Test_generateRevealKeyEncryptedSignature(t *testing.T) {
- rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "cbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
c := newConversation(otrV3{}, rnd)
c.initAKE()
@@ -395,7 +406,12 @@ func Test_generateRevealKeyEncryptedSignature(t *testing.T) {
}
func Test_generateSigKeyEncryptedSignature(t *testing.T) {
- rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"})
+ rnd := fixedRand([]string{"bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ "bbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+ })
c := newConversation(otrV3{}, rnd)
c.initAKE()
diff --git a/debian/changelog b/debian/changelog
index 486179e..7c45b5d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+golang-github-twstrike-otr3 (0.0~git20161015.0.744856d-3.1) unstable; urgency=medium
+
+ * Non maintainer upload by the Reproducible Builds team.
+ * No source change upload to rebuild on buildd with .buildinfo files.
+
+ -- Holger Levsen <holger@debian.org> Sat, 09 Jan 2021 17:01:32 +0100
+
golang-github-twstrike-otr3 (0.0~git20161015.0.744856d-3) unstable; urgency=medium
* Add patch from upstream to fix builds with Go 1.11.
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..b4de394
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+11
diff --git a/debian/control b/debian/control
index f146592..a8f55f9 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Maintainer: Debian Go Packaging Team <pkg-go-maintainers@lists.alioth.debian.org
Uploaders: Sascha Steinbiss <satta@debian.org>
Section: devel
Priority: optional
-Build-Depends: debhelper-compat (= 12),
+Build-Depends: debhelper (>= 11),
dh-golang,
golang-go
Standards-Version: 4.1.4
diff --git a/debian/gitlab-ci.yml b/debian/gitlab-ci.yml
index 594e14e..5c8c31b 100644
--- a/debian/gitlab-ci.yml
+++ b/debian/gitlab-ci.yml
@@ -1,6 +1,28 @@
+
# auto-generated, DO NOT MODIFY.
# The authoritative copy of this file lives at:
-# https://salsa.debian.org/go-team/infra/pkg-go-tools/blob/master/config/gitlabciyml.go
----
-include:
- - https://salsa.debian.org/go-team/infra/pkg-go-tools/-/raw/master/pipeline/test-archive.yml
+# https://salsa.debian.org/go-team/ci/blob/master/cmd/ci/gitlabciyml.go
+
+# TODO: publish under debian-go-team/ci
+image: stapelberg/ci2
+
+test_the_archive:
+ artifacts:
+ paths:
+ - before-applying-commit.json
+ - after-applying-commit.json
+ script:
+ # Create an overlay to discard writes to /srv/gopath/src after the build:
+ - "rm -rf /cache/overlay/{upper,work}"
+ - "mkdir -p /cache/overlay/{upper,work}"
+ - "mount -t overlay overlay -o lowerdir=/srv/gopath/src,upperdir=/cache/overlay/upper,workdir=/cache/overlay/work /srv/gopath/src"
+ - "export GOPATH=/srv/gopath"
+ - "export GOCACHE=/cache/go"
+ # Build the world as-is:
+ - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > before-applying-commit.json"
+ # Copy this package into the overlay:
+ - "GBP_CONF_FILES=:debian/gbp.conf gbp buildpackage --git-no-pristine-tar --git-ignore-branch --git-ignore-new --git-export-dir=/tmp/export --git-no-overlay --git-tarball-dir=/nonexistant --git-cleaner=/bin/true --git-builder='dpkg-buildpackage -S -d --no-sign'"
+ - "pgt-gopath -dsc /tmp/export/*.dsc"
+ # Rebuild the world:
+ - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > after-applying-commit.json"
+ - "ci-diff before-applying-commit.json after-applying-commit.json"
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
deleted file mode 100644
index efefa27..0000000
--- a/debian/upstream/metadata
+++ /dev/null
@@ -1,4 +0,0 @@
-Bug-Database: https://github.com/twstrike/otr3/issues
-Bug-Submit: https://github.com/twstrike/otr3/issues/new
-Repository: https://github.com/twstrike/otr3.git
-Repository-Browse: https://github.com/twstrike/otr3
diff --git a/keys_test.go b/keys_test.go
index 04c8eaf..7ffbeb5 100644
--- a/keys_test.go
+++ b/keys_test.go
@@ -979,13 +979,13 @@ func Test_ImportKeysFromFile_willReturnAnErrorIfAskedToReadAFileNameThatDoesntEx
}
func Test_ImportKeysFromFile_willReturnAValidAccountReadFromAFile(t *testing.T) {
- res, err := ImportKeysFromFile("test_resources/valid_key.asc")
+ res, err := ImportKeysFromFile("/tmp/valid_key.asc")
assertDeepEquals(t, len(res), 1)
assertDeepEquals(t, err, nil)
}
func Test_ImportKeysFromFile_willReturnAnErrorIfTheFileIsinvalid(t *testing.T) {
- _, err := ImportKeysFromFile("test_resources/invalid_key.asc")
+ _, err := ImportKeysFromFile("/tmp/invalid_key.asc")
assertDeepEquals(t, err, newOtrError("couldn't import data into private key"))
}
@@ -1061,12 +1061,12 @@ func Test_ExportKeysToFile_exportsKeysToAFile(t *testing.T) {
priv.Parse(serializedPrivateKey)
acc := &Account{Name: "hello", Protocol: "go-xmpp", Key: priv}
- err := ExportKeysToFile([]*Account{acc}, "test_resources/test_export_of_keys.blah")
+ err := ExportKeysToFile([]*Account{acc}, "/tmp/test_export_of_keys.blah")
assertNil(t, err)
- res, err2 := ImportKeysFromFile("test_resources/test_export_of_keys.blah")
+ res, err2 := ImportKeysFromFile("/tmp/test_export_of_keys.blah")
- defer os.Remove("test_resources/test_export_of_keys.blah")
+ defer os.Remove("/tmp/test_export_of_keys.blah")
assertNil(t, err2)
assertDeepEquals(t, res[0].Key, acc.Key)
Debdiff
File lists identical (after any substitutions)
No differences were encountered in the control files