github.com/maenmax/kairep@v0.0.0-20210218001208-55bf3df36788/src/golang.org/x/crypto/otr/otr.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package otr implements the Off The Record protocol as specified in
     6  // http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html
     7  package otr // import "golang.org/x/crypto/otr"
     8  
     9  import (
    10  	"bytes"
    11  	"crypto/aes"
    12  	"crypto/cipher"
    13  	"crypto/dsa"
    14  	"crypto/hmac"
    15  	"crypto/rand"
    16  	"crypto/sha1"
    17  	"crypto/sha256"
    18  	"crypto/subtle"
    19  	"encoding/base64"
    20  	"encoding/hex"
    21  	"errors"
    22  	"hash"
    23  	"io"
    24  	"math/big"
    25  	"strconv"
    26  )
    27  
    28  // SecurityChange describes a change in the security state of a Conversation.
    29  type SecurityChange int
    30  
    31  const (
    32  	NoChange SecurityChange = iota
    33  	// NewKeys indicates that a key exchange has completed. This occurs
    34  	// when a conversation first becomes encrypted, and when the keys are
    35  	// renegotiated within an encrypted conversation.
    36  	NewKeys
    37  	// SMPSecretNeeded indicates that the peer has started an
    38  	// authentication and that we need to supply a secret. Call SMPQuestion
    39  	// to get the optional, human readable challenge and then Authenticate
    40  	// to supply the matching secret.
    41  	SMPSecretNeeded
    42  	// SMPComplete indicates that an authentication completed. The identity
    43  	// of the peer has now been confirmed.
    44  	SMPComplete
    45  	// SMPFailed indicates that an authentication failed.
    46  	SMPFailed
    47  	// ConversationEnded indicates that the peer ended the secure
    48  	// conversation.
    49  	ConversationEnded
    50  )
    51  
    52  // QueryMessage can be sent to a peer to start an OTR conversation.
    53  var QueryMessage = "?OTRv2?"
    54  
    55  // ErrorPrefix can be used to make an OTR error by appending an error message
    56  // to it.
    57  var ErrorPrefix = "?OTR Error:"
    58  
    59  var (
    60  	fragmentPartSeparator = []byte(",")
    61  	fragmentPrefix        = []byte("?OTR,")
    62  	msgPrefix             = []byte("?OTR:")
    63  	queryMarker           = []byte("?OTR")
    64  )
    65  
    66  // isQuery attempts to parse an OTR query from msg and returns the greatest
    67  // common version, or 0 if msg is not an OTR query.
    68  func isQuery(msg []byte) (greatestCommonVersion int) {
    69  	pos := bytes.Index(msg, queryMarker)
    70  	if pos == -1 {
    71  		return 0
    72  	}
    73  	for i, c := range msg[pos+len(queryMarker):] {
    74  		if i == 0 {
    75  			if c == '?' {
    76  				// Indicates support for version 1, but we don't
    77  				// implement that.
    78  				continue
    79  			}
    80  
    81  			if c != 'v' {
    82  				// Invalid message
    83  				return 0
    84  			}
    85  
    86  			continue
    87  		}
    88  
    89  		if c == '?' {
    90  			// End of message
    91  			return
    92  		}
    93  
    94  		if c == ' ' || c == '\t' {
    95  			// Probably an invalid message
    96  			return 0
    97  		}
    98  
    99  		if c == '2' {
   100  			greatestCommonVersion = 2
   101  		}
   102  	}
   103  
   104  	return 0
   105  }
   106  
   107  const (
   108  	statePlaintext = iota
   109  	stateEncrypted
   110  	stateFinished
   111  )
   112  
   113  const (
   114  	authStateNone = iota
   115  	authStateAwaitingDHKey
   116  	authStateAwaitingRevealSig
   117  	authStateAwaitingSig
   118  )
   119  
   120  const (
   121  	msgTypeDHCommit  = 2
   122  	msgTypeData      = 3
   123  	msgTypeDHKey     = 10
   124  	msgTypeRevealSig = 17
   125  	msgTypeSig       = 18
   126  )
   127  
   128  const (
   129  	// If the requested fragment size is less than this, it will be ignored.
   130  	minFragmentSize = 18
   131  	// Messages are padded to a multiple of this number of bytes.
   132  	paddingGranularity = 256
   133  	// The number of bytes in a Diffie-Hellman private value (320-bits).
   134  	dhPrivateBytes = 40
   135  	// The number of bytes needed to represent an element of the DSA
   136  	// subgroup (160-bits).
   137  	dsaSubgroupBytes = 20
   138  	// The number of bytes of the MAC that are sent on the wire (160-bits).
   139  	macPrefixBytes = 20
   140  )
   141  
   142  // These are the global, common group parameters for OTR.
   143  var (
   144  	p       *big.Int // group prime
   145  	g       *big.Int // group generator
   146  	q       *big.Int // group order
   147  	pMinus2 *big.Int
   148  )
   149  
   150  func init() {
   151  	p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 16)
   152  	q, _ = new(big.Int).SetString("7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68948127044533E63A0105DF531D89CD9128A5043CC71A026EF7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9EE1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AFC1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36B3861AA7255E4C0278BA36046511B993FFFFFFFFFFFFFFFF", 16)
   153  	g = new(big.Int).SetInt64(2)
   154  	pMinus2 = new(big.Int).Sub(p, g)
   155  }
   156  
   157  // Conversation represents a relation with a peer. The zero value is a valid
   158  // Conversation, although PrivateKey must be set.
   159  //
   160  // When communicating with a peer, all inbound messages should be passed to
   161  // Conversation.Receive and all outbound messages to Conversation.Send. The
   162  // Conversation will take care of maintaining the encryption state and
   163  // negotiating encryption as needed.
   164  type Conversation struct {
   165  	// PrivateKey contains the private key to use to sign key exchanges.
   166  	PrivateKey *PrivateKey
   167  
   168  	// Rand can be set to override the entropy source. Otherwise,
   169  	// crypto/rand will be used.
   170  	Rand io.Reader
   171  	// If FragmentSize is set, all messages produced by Receive and Send
   172  	// will be fragmented into messages of, at most, this number of bytes.
   173  	FragmentSize int
   174  
   175  	// Once Receive has returned NewKeys once, the following fields are
   176  	// valid.
   177  	SSID           [8]byte
   178  	TheirPublicKey PublicKey
   179  
   180  	state, authState int
   181  
   182  	r       [16]byte
   183  	x, y    *big.Int
   184  	gx, gy  *big.Int
   185  	gxBytes []byte
   186  	digest  [sha256.Size]byte
   187  
   188  	revealKeys, sigKeys akeKeys
   189  
   190  	myKeyId         uint32
   191  	myCurrentDHPub  *big.Int
   192  	myCurrentDHPriv *big.Int
   193  	myLastDHPub     *big.Int
   194  	myLastDHPriv    *big.Int
   195  
   196  	theirKeyId        uint32
   197  	theirCurrentDHPub *big.Int
   198  	theirLastDHPub    *big.Int
   199  
   200  	keySlots [4]keySlot
   201  
   202  	myCounter    [8]byte
   203  	theirLastCtr [8]byte
   204  	oldMACs      []byte
   205  
   206  	k, n int // fragment state
   207  	frag []byte
   208  
   209  	smp smpState
   210  }
   211  
   212  // A keySlot contains key material for a specific (their keyid, my keyid) pair.
   213  type keySlot struct {
   214  	// used is true if this slot is valid. If false, it's free for reuse.
   215  	used                   bool
   216  	theirKeyId             uint32
   217  	myKeyId                uint32
   218  	sendAESKey, recvAESKey []byte
   219  	sendMACKey, recvMACKey []byte
   220  	theirLastCtr           [8]byte
   221  }
   222  
   223  // akeKeys are generated during key exchange. There's one set for the reveal
   224  // signature message and another for the signature message. In the protocol
   225  // spec the latter are indicated with a prime mark.
   226  type akeKeys struct {
   227  	c      [16]byte
   228  	m1, m2 [32]byte
   229  }
   230  
   231  func (c *Conversation) rand() io.Reader {
   232  	if c.Rand != nil {
   233  		return c.Rand
   234  	}
   235  	return rand.Reader
   236  }
   237  
   238  func (c *Conversation) randMPI(buf []byte) *big.Int {
   239  	_, err := io.ReadFull(c.rand(), buf)
   240  	if err != nil {
   241  		panic("otr: short read from random source")
   242  	}
   243  
   244  	return new(big.Int).SetBytes(buf)
   245  }
   246  
   247  // tlv represents the type-length value from the protocol.
   248  type tlv struct {
   249  	typ, length uint16
   250  	data        []byte
   251  }
   252  
   253  const (
   254  	tlvTypePadding          = 0
   255  	tlvTypeDisconnected     = 1
   256  	tlvTypeSMP1             = 2
   257  	tlvTypeSMP2             = 3
   258  	tlvTypeSMP3             = 4
   259  	tlvTypeSMP4             = 5
   260  	tlvTypeSMPAbort         = 6
   261  	tlvTypeSMP1WithQuestion = 7
   262  )
   263  
   264  // Receive handles a message from a peer. It returns a human readable message,
   265  // an indicator of whether that message was encrypted, a hint about the
   266  // encryption state and zero or more messages to send back to the peer.
   267  // These messages do not need to be passed to Send before transmission.
   268  func (c *Conversation) Receive(in []byte) (out []byte, encrypted bool, change SecurityChange, toSend [][]byte, err error) {
   269  	if bytes.HasPrefix(in, fragmentPrefix) {
   270  		in, err = c.processFragment(in)
   271  		if in == nil || err != nil {
   272  			return
   273  		}
   274  	}
   275  
   276  	if bytes.HasPrefix(in, msgPrefix) && in[len(in)-1] == '.' {
   277  		in = in[len(msgPrefix) : len(in)-1]
   278  	} else if version := isQuery(in); version > 0 {
   279  		c.authState = authStateAwaitingDHKey
   280  		c.reset()
   281  		toSend = c.encode(c.generateDHCommit())
   282  		return
   283  	} else {
   284  		// plaintext message
   285  		out = in
   286  		return
   287  	}
   288  
   289  	msg := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
   290  	msgLen, err := base64.StdEncoding.Decode(msg, in)
   291  	if err != nil {
   292  		err = errors.New("otr: invalid base64 encoding in message")
   293  		return
   294  	}
   295  	msg = msg[:msgLen]
   296  
   297  	// The first two bytes are the protocol version (2)
   298  	if len(msg) < 3 || msg[0] != 0 || msg[1] != 2 {
   299  		err = errors.New("otr: invalid OTR message")
   300  		return
   301  	}
   302  
   303  	msgType := int(msg[2])
   304  	msg = msg[3:]
   305  
   306  	switch msgType {
   307  	case msgTypeDHCommit:
   308  		switch c.authState {
   309  		case authStateNone:
   310  			c.authState = authStateAwaitingRevealSig
   311  			if err = c.processDHCommit(msg); err != nil {
   312  				return
   313  			}
   314  			c.reset()
   315  			toSend = c.encode(c.generateDHKey())
   316  			return
   317  		case authStateAwaitingDHKey:
   318  			// This is a 'SYN-crossing'. The greater digest wins.
   319  			var cmp int
   320  			if cmp, err = c.compareToDHCommit(msg); err != nil {
   321  				return
   322  			}
   323  			if cmp > 0 {
   324  				// We win. Retransmit DH commit.
   325  				toSend = c.encode(c.serializeDHCommit())
   326  				return
   327  			} else {
   328  				// They win. We forget about our DH commit.
   329  				c.authState = authStateAwaitingRevealSig
   330  				if err = c.processDHCommit(msg); err != nil {
   331  					return
   332  				}
   333  				c.reset()
   334  				toSend = c.encode(c.generateDHKey())
   335  				return
   336  			}
   337  		case authStateAwaitingRevealSig:
   338  			if err = c.processDHCommit(msg); err != nil {
   339  				return
   340  			}
   341  			toSend = c.encode(c.serializeDHKey())
   342  		case authStateAwaitingSig:
   343  			if err = c.processDHCommit(msg); err != nil {
   344  				return
   345  			}
   346  			c.reset()
   347  			toSend = c.encode(c.generateDHKey())
   348  			c.authState = authStateAwaitingRevealSig
   349  		default:
   350  			panic("bad state")
   351  		}
   352  	case msgTypeDHKey:
   353  		switch c.authState {
   354  		case authStateAwaitingDHKey:
   355  			var isSame bool
   356  			if isSame, err = c.processDHKey(msg); err != nil {
   357  				return
   358  			}
   359  			if isSame {
   360  				err = errors.New("otr: unexpected duplicate DH key")
   361  				return
   362  			}
   363  			toSend = c.encode(c.generateRevealSig())
   364  			c.authState = authStateAwaitingSig
   365  		case authStateAwaitingSig:
   366  			var isSame bool
   367  			if isSame, err = c.processDHKey(msg); err != nil {
   368  				return
   369  			}
   370  			if isSame {
   371  				toSend = c.encode(c.serializeDHKey())
   372  			}
   373  		}
   374  	case msgTypeRevealSig:
   375  		if c.authState != authStateAwaitingRevealSig {
   376  			return
   377  		}
   378  		if err = c.processRevealSig(msg); err != nil {
   379  			return
   380  		}
   381  		toSend = c.encode(c.generateSig())
   382  		c.authState = authStateNone
   383  		c.state = stateEncrypted
   384  		change = NewKeys
   385  	case msgTypeSig:
   386  		if c.authState != authStateAwaitingSig {
   387  			return
   388  		}
   389  		if err = c.processSig(msg); err != nil {
   390  			return
   391  		}
   392  		c.authState = authStateNone
   393  		c.state = stateEncrypted
   394  		change = NewKeys
   395  	case msgTypeData:
   396  		if c.state != stateEncrypted {
   397  			err = errors.New("otr: encrypted message received without encrypted session established")
   398  			return
   399  		}
   400  		var tlvs []tlv
   401  		out, tlvs, err = c.processData(msg)
   402  		encrypted = true
   403  
   404  	EachTLV:
   405  		for _, inTLV := range tlvs {
   406  			switch inTLV.typ {
   407  			case tlvTypeDisconnected:
   408  				change = ConversationEnded
   409  				c.state = stateFinished
   410  				break EachTLV
   411  			case tlvTypeSMP1, tlvTypeSMP2, tlvTypeSMP3, tlvTypeSMP4, tlvTypeSMPAbort, tlvTypeSMP1WithQuestion:
   412  				var reply tlv
   413  				var complete bool
   414  				reply, complete, err = c.processSMP(inTLV)
   415  				if err == smpSecretMissingError {
   416  					err = nil
   417  					change = SMPSecretNeeded
   418  					c.smp.saved = &inTLV
   419  					return
   420  				}
   421  				if err == smpFailureError {
   422  					err = nil
   423  					change = SMPFailed
   424  				} else if complete {
   425  					change = SMPComplete
   426  				}
   427  				if reply.typ != 0 {
   428  					toSend = c.encode(c.generateData(nil, &reply))
   429  				}
   430  				break EachTLV
   431  			default:
   432  				// skip unknown TLVs
   433  			}
   434  		}
   435  	default:
   436  		err = errors.New("otr: unknown message type " + strconv.Itoa(msgType))
   437  	}
   438  
   439  	return
   440  }
   441  
   442  // Send takes a human readable message from the local user, possibly encrypts
   443  // it and returns zero one or more messages to send to the peer.
   444  func (c *Conversation) Send(msg []byte) ([][]byte, error) {
   445  	switch c.state {
   446  	case statePlaintext:
   447  		return [][]byte{msg}, nil
   448  	case stateEncrypted:
   449  		return c.encode(c.generateData(msg, nil)), nil
   450  	case stateFinished:
   451  		return nil, errors.New("otr: cannot send message because secure conversation has finished")
   452  	}
   453  
   454  	return nil, errors.New("otr: cannot send message in current state")
   455  }
   456  
   457  // SMPQuestion returns the human readable challenge question from the peer.
   458  // It's only valid after Receive has returned SMPSecretNeeded.
   459  func (c *Conversation) SMPQuestion() string {
   460  	return c.smp.question
   461  }
   462  
   463  // Authenticate begins an authentication with the peer. Authentication involves
   464  // an optional challenge message and a shared secret. The authentication
   465  // proceeds until either Receive returns SMPComplete, SMPSecretNeeded (which
   466  // indicates that a new authentication is happening and thus this one was
   467  // aborted) or SMPFailed.
   468  func (c *Conversation) Authenticate(question string, mutualSecret []byte) (toSend [][]byte, err error) {
   469  	if c.state != stateEncrypted {
   470  		err = errors.New("otr: can't authenticate a peer without a secure conversation established")
   471  		return
   472  	}
   473  
   474  	if c.smp.saved != nil {
   475  		c.calcSMPSecret(mutualSecret, false /* they started it */)
   476  
   477  		var out tlv
   478  		var complete bool
   479  		out, complete, err = c.processSMP(*c.smp.saved)
   480  		if complete {
   481  			panic("SMP completed on the first message")
   482  		}
   483  		c.smp.saved = nil
   484  		if out.typ != 0 {
   485  			toSend = c.encode(c.generateData(nil, &out))
   486  		}
   487  		return
   488  	}
   489  
   490  	c.calcSMPSecret(mutualSecret, true /* we started it */)
   491  	outs := c.startSMP(question)
   492  	for _, out := range outs {
   493  		toSend = append(toSend, c.encode(c.generateData(nil, &out))...)
   494  	}
   495  	return
   496  }
   497  
   498  // End ends a secure conversation by generating a termination message for
   499  // the peer and switches to unencrypted communication.
   500  func (c *Conversation) End() (toSend [][]byte) {
   501  	switch c.state {
   502  	case statePlaintext:
   503  		return nil
   504  	case stateEncrypted:
   505  		c.state = statePlaintext
   506  		return c.encode(c.generateData(nil, &tlv{typ: tlvTypeDisconnected}))
   507  	case stateFinished:
   508  		c.state = statePlaintext
   509  		return nil
   510  	}
   511  	panic("unreachable")
   512  }
   513  
   514  // IsEncrypted returns true if a message passed to Send would be encrypted
   515  // before transmission. This result remains valid until the next call to
   516  // Receive or End, which may change the state of the Conversation.
   517  func (c *Conversation) IsEncrypted() bool {
   518  	return c.state == stateEncrypted
   519  }
   520  
   521  var fragmentError = errors.New("otr: invalid OTR fragment")
   522  
   523  // processFragment processes a fragmented OTR message and possibly returns a
   524  // complete message. Fragmented messages look like "?OTR,k,n,msg," where k is
   525  // the fragment number (starting from 1), n is the number of fragments in this
   526  // message and msg is a substring of the base64 encoded message.
   527  func (c *Conversation) processFragment(in []byte) (out []byte, err error) {
   528  	in = in[len(fragmentPrefix):] // remove "?OTR,"
   529  	parts := bytes.Split(in, fragmentPartSeparator)
   530  	if len(parts) != 4 || len(parts[3]) != 0 {
   531  		return nil, fragmentError
   532  	}
   533  
   534  	k, err := strconv.Atoi(string(parts[0]))
   535  	if err != nil {
   536  		return nil, fragmentError
   537  	}
   538  
   539  	n, err := strconv.Atoi(string(parts[1]))
   540  	if err != nil {
   541  		return nil, fragmentError
   542  	}
   543  
   544  	if k < 1 || n < 1 || k > n {
   545  		return nil, fragmentError
   546  	}
   547  
   548  	if k == 1 {
   549  		c.frag = append(c.frag[:0], parts[2]...)
   550  		c.k, c.n = k, n
   551  	} else if n == c.n && k == c.k+1 {
   552  		c.frag = append(c.frag, parts[2]...)
   553  		c.k++
   554  	} else {
   555  		c.frag = c.frag[:0]
   556  		c.n, c.k = 0, 0
   557  	}
   558  
   559  	if c.n > 0 && c.k == c.n {
   560  		c.n, c.k = 0, 0
   561  		return c.frag, nil
   562  	}
   563  
   564  	return nil, nil
   565  }
   566  
   567  func (c *Conversation) generateDHCommit() []byte {
   568  	_, err := io.ReadFull(c.rand(), c.r[:])
   569  	if err != nil {
   570  		panic("otr: short read from random source")
   571  	}
   572  
   573  	var xBytes [dhPrivateBytes]byte
   574  	c.x = c.randMPI(xBytes[:])
   575  	c.gx = new(big.Int).Exp(g, c.x, p)
   576  	c.gy = nil
   577  	c.gxBytes = appendMPI(nil, c.gx)
   578  
   579  	h := sha256.New()
   580  	h.Write(c.gxBytes)
   581  	h.Sum(c.digest[:0])
   582  
   583  	aesCipher, err := aes.NewCipher(c.r[:])
   584  	if err != nil {
   585  		panic(err.Error())
   586  	}
   587  
   588  	var iv [aes.BlockSize]byte
   589  	ctr := cipher.NewCTR(aesCipher, iv[:])
   590  	ctr.XORKeyStream(c.gxBytes, c.gxBytes)
   591  
   592  	return c.serializeDHCommit()
   593  }
   594  
   595  func (c *Conversation) serializeDHCommit() []byte {
   596  	var ret []byte
   597  	ret = appendU16(ret, 2) // protocol version
   598  	ret = append(ret, msgTypeDHCommit)
   599  	ret = appendData(ret, c.gxBytes)
   600  	ret = appendData(ret, c.digest[:])
   601  	return ret
   602  }
   603  
   604  func (c *Conversation) processDHCommit(in []byte) error {
   605  	var ok1, ok2 bool
   606  	c.gxBytes, in, ok1 = getData(in)
   607  	digest, in, ok2 := getData(in)
   608  	if !ok1 || !ok2 || len(in) > 0 {
   609  		return errors.New("otr: corrupt DH commit message")
   610  	}
   611  	copy(c.digest[:], digest)
   612  	return nil
   613  }
   614  
   615  func (c *Conversation) compareToDHCommit(in []byte) (int, error) {
   616  	_, in, ok1 := getData(in)
   617  	digest, in, ok2 := getData(in)
   618  	if !ok1 || !ok2 || len(in) > 0 {
   619  		return 0, errors.New("otr: corrupt DH commit message")
   620  	}
   621  	return bytes.Compare(c.digest[:], digest), nil
   622  }
   623  
   624  func (c *Conversation) generateDHKey() []byte {
   625  	var yBytes [dhPrivateBytes]byte
   626  	c.y = c.randMPI(yBytes[:])
   627  	c.gy = new(big.Int).Exp(g, c.y, p)
   628  	return c.serializeDHKey()
   629  }
   630  
   631  func (c *Conversation) serializeDHKey() []byte {
   632  	var ret []byte
   633  	ret = appendU16(ret, 2) // protocol version
   634  	ret = append(ret, msgTypeDHKey)
   635  	ret = appendMPI(ret, c.gy)
   636  	return ret
   637  }
   638  
   639  func (c *Conversation) processDHKey(in []byte) (isSame bool, err error) {
   640  	gy, in, ok := getMPI(in)
   641  	if !ok {
   642  		err = errors.New("otr: corrupt DH key message")
   643  		return
   644  	}
   645  	if gy.Cmp(g) < 0 || gy.Cmp(pMinus2) > 0 {
   646  		err = errors.New("otr: DH value out of range")
   647  		return
   648  	}
   649  	if c.gy != nil {
   650  		isSame = c.gy.Cmp(gy) == 0
   651  		return
   652  	}
   653  	c.gy = gy
   654  	return
   655  }
   656  
   657  func (c *Conversation) generateEncryptedSignature(keys *akeKeys, xFirst bool) ([]byte, []byte) {
   658  	var xb []byte
   659  	xb = c.PrivateKey.PublicKey.Serialize(xb)
   660  
   661  	var verifyData []byte
   662  	if xFirst {
   663  		verifyData = appendMPI(verifyData, c.gx)
   664  		verifyData = appendMPI(verifyData, c.gy)
   665  	} else {
   666  		verifyData = appendMPI(verifyData, c.gy)
   667  		verifyData = appendMPI(verifyData, c.gx)
   668  	}
   669  	verifyData = append(verifyData, xb...)
   670  	verifyData = appendU32(verifyData, c.myKeyId)
   671  
   672  	mac := hmac.New(sha256.New, keys.m1[:])
   673  	mac.Write(verifyData)
   674  	mb := mac.Sum(nil)
   675  
   676  	xb = appendU32(xb, c.myKeyId)
   677  	xb = append(xb, c.PrivateKey.Sign(c.rand(), mb)...)
   678  
   679  	aesCipher, err := aes.NewCipher(keys.c[:])
   680  	if err != nil {
   681  		panic(err.Error())
   682  	}
   683  	var iv [aes.BlockSize]byte
   684  	ctr := cipher.NewCTR(aesCipher, iv[:])
   685  	ctr.XORKeyStream(xb, xb)
   686  
   687  	mac = hmac.New(sha256.New, keys.m2[:])
   688  	encryptedSig := appendData(nil, xb)
   689  	mac.Write(encryptedSig)
   690  
   691  	return encryptedSig, mac.Sum(nil)
   692  }
   693  
   694  func (c *Conversation) generateRevealSig() []byte {
   695  	s := new(big.Int).Exp(c.gy, c.x, p)
   696  	c.calcAKEKeys(s)
   697  	c.myKeyId++
   698  
   699  	encryptedSig, mac := c.generateEncryptedSignature(&c.revealKeys, true /* gx comes first */)
   700  
   701  	c.myCurrentDHPub = c.gx
   702  	c.myCurrentDHPriv = c.x
   703  	c.rotateDHKeys()
   704  	incCounter(&c.myCounter)
   705  
   706  	var ret []byte
   707  	ret = appendU16(ret, 2)
   708  	ret = append(ret, msgTypeRevealSig)
   709  	ret = appendData(ret, c.r[:])
   710  	ret = append(ret, encryptedSig...)
   711  	ret = append(ret, mac[:20]...)
   712  	return ret
   713  }
   714  
   715  func (c *Conversation) processEncryptedSig(encryptedSig, theirMAC []byte, keys *akeKeys, xFirst bool) error {
   716  	mac := hmac.New(sha256.New, keys.m2[:])
   717  	mac.Write(appendData(nil, encryptedSig))
   718  	myMAC := mac.Sum(nil)[:20]
   719  
   720  	if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 {
   721  		return errors.New("bad signature MAC in encrypted signature")
   722  	}
   723  
   724  	aesCipher, err := aes.NewCipher(keys.c[:])
   725  	if err != nil {
   726  		panic(err.Error())
   727  	}
   728  	var iv [aes.BlockSize]byte
   729  	ctr := cipher.NewCTR(aesCipher, iv[:])
   730  	ctr.XORKeyStream(encryptedSig, encryptedSig)
   731  
   732  	sig := encryptedSig
   733  	sig, ok1 := c.TheirPublicKey.Parse(sig)
   734  	keyId, sig, ok2 := getU32(sig)
   735  	if !ok1 || !ok2 {
   736  		return errors.New("otr: corrupt encrypted signature")
   737  	}
   738  
   739  	var verifyData []byte
   740  	if xFirst {
   741  		verifyData = appendMPI(verifyData, c.gx)
   742  		verifyData = appendMPI(verifyData, c.gy)
   743  	} else {
   744  		verifyData = appendMPI(verifyData, c.gy)
   745  		verifyData = appendMPI(verifyData, c.gx)
   746  	}
   747  	verifyData = c.TheirPublicKey.Serialize(verifyData)
   748  	verifyData = appendU32(verifyData, keyId)
   749  
   750  	mac = hmac.New(sha256.New, keys.m1[:])
   751  	mac.Write(verifyData)
   752  	mb := mac.Sum(nil)
   753  
   754  	sig, ok1 = c.TheirPublicKey.Verify(mb, sig)
   755  	if !ok1 {
   756  		return errors.New("bad signature in encrypted signature")
   757  	}
   758  	if len(sig) > 0 {
   759  		return errors.New("corrupt encrypted signature")
   760  	}
   761  
   762  	c.theirKeyId = keyId
   763  	zero(c.theirLastCtr[:])
   764  	return nil
   765  }
   766  
   767  func (c *Conversation) processRevealSig(in []byte) error {
   768  	r, in, ok1 := getData(in)
   769  	encryptedSig, in, ok2 := getData(in)
   770  	theirMAC := in
   771  	if !ok1 || !ok2 || len(theirMAC) != 20 {
   772  		return errors.New("otr: corrupt reveal signature message")
   773  	}
   774  
   775  	aesCipher, err := aes.NewCipher(r)
   776  	if err != nil {
   777  		return errors.New("otr: cannot create AES cipher from reveal signature message: " + err.Error())
   778  	}
   779  	var iv [aes.BlockSize]byte
   780  	ctr := cipher.NewCTR(aesCipher, iv[:])
   781  	ctr.XORKeyStream(c.gxBytes, c.gxBytes)
   782  	h := sha256.New()
   783  	h.Write(c.gxBytes)
   784  	digest := h.Sum(nil)
   785  	if len(digest) != len(c.digest) || subtle.ConstantTimeCompare(digest, c.digest[:]) == 0 {
   786  		return errors.New("otr: bad commit MAC in reveal signature message")
   787  	}
   788  	var rest []byte
   789  	c.gx, rest, ok1 = getMPI(c.gxBytes)
   790  	if !ok1 || len(rest) > 0 {
   791  		return errors.New("otr: gx corrupt after decryption")
   792  	}
   793  	if c.gx.Cmp(g) < 0 || c.gx.Cmp(pMinus2) > 0 {
   794  		return errors.New("otr: DH value out of range")
   795  	}
   796  	s := new(big.Int).Exp(c.gx, c.y, p)
   797  	c.calcAKEKeys(s)
   798  
   799  	if err := c.processEncryptedSig(encryptedSig, theirMAC, &c.revealKeys, true /* gx comes first */); err != nil {
   800  		return errors.New("otr: in reveal signature message: " + err.Error())
   801  	}
   802  
   803  	c.theirCurrentDHPub = c.gx
   804  	c.theirLastDHPub = nil
   805  
   806  	return nil
   807  }
   808  
   809  func (c *Conversation) generateSig() []byte {
   810  	c.myKeyId++
   811  
   812  	encryptedSig, mac := c.generateEncryptedSignature(&c.sigKeys, false /* gy comes first */)
   813  
   814  	c.myCurrentDHPub = c.gy
   815  	c.myCurrentDHPriv = c.y
   816  	c.rotateDHKeys()
   817  	incCounter(&c.myCounter)
   818  
   819  	var ret []byte
   820  	ret = appendU16(ret, 2)
   821  	ret = append(ret, msgTypeSig)
   822  	ret = append(ret, encryptedSig...)
   823  	ret = append(ret, mac[:macPrefixBytes]...)
   824  	return ret
   825  }
   826  
   827  func (c *Conversation) processSig(in []byte) error {
   828  	encryptedSig, in, ok1 := getData(in)
   829  	theirMAC := in
   830  	if !ok1 || len(theirMAC) != macPrefixBytes {
   831  		return errors.New("otr: corrupt signature message")
   832  	}
   833  
   834  	if err := c.processEncryptedSig(encryptedSig, theirMAC, &c.sigKeys, false /* gy comes first */); err != nil {
   835  		return errors.New("otr: in signature message: " + err.Error())
   836  	}
   837  
   838  	c.theirCurrentDHPub = c.gy
   839  	c.theirLastDHPub = nil
   840  
   841  	return nil
   842  }
   843  
   844  func (c *Conversation) rotateDHKeys() {
   845  	// evict slots using our retired key id
   846  	for i := range c.keySlots {
   847  		slot := &c.keySlots[i]
   848  		if slot.used && slot.myKeyId == c.myKeyId-1 {
   849  			slot.used = false
   850  			c.oldMACs = append(c.oldMACs, slot.recvMACKey...)
   851  		}
   852  	}
   853  
   854  	c.myLastDHPriv = c.myCurrentDHPriv
   855  	c.myLastDHPub = c.myCurrentDHPub
   856  
   857  	var xBytes [dhPrivateBytes]byte
   858  	c.myCurrentDHPriv = c.randMPI(xBytes[:])
   859  	c.myCurrentDHPub = new(big.Int).Exp(g, c.myCurrentDHPriv, p)
   860  	c.myKeyId++
   861  }
   862  
   863  func (c *Conversation) processData(in []byte) (out []byte, tlvs []tlv, err error) {
   864  	origIn := in
   865  	flags, in, ok1 := getU8(in)
   866  	theirKeyId, in, ok2 := getU32(in)
   867  	myKeyId, in, ok3 := getU32(in)
   868  	y, in, ok4 := getMPI(in)
   869  	counter, in, ok5 := getNBytes(in, 8)
   870  	encrypted, in, ok6 := getData(in)
   871  	macedData := origIn[:len(origIn)-len(in)]
   872  	theirMAC, in, ok7 := getNBytes(in, macPrefixBytes)
   873  	_, in, ok8 := getData(in)
   874  	if !ok1 || !ok2 || !ok3 || !ok4 || !ok5 || !ok6 || !ok7 || !ok8 || len(in) > 0 {
   875  		err = errors.New("otr: corrupt data message")
   876  		return
   877  	}
   878  
   879  	ignoreErrors := flags&1 != 0
   880  
   881  	slot, err := c.calcDataKeys(myKeyId, theirKeyId)
   882  	if err != nil {
   883  		if ignoreErrors {
   884  			err = nil
   885  		}
   886  		return
   887  	}
   888  
   889  	mac := hmac.New(sha1.New, slot.recvMACKey)
   890  	mac.Write([]byte{0, 2, 3})
   891  	mac.Write(macedData)
   892  	myMAC := mac.Sum(nil)
   893  	if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 {
   894  		if !ignoreErrors {
   895  			err = errors.New("otr: bad MAC on data message")
   896  		}
   897  		return
   898  	}
   899  
   900  	if bytes.Compare(counter, slot.theirLastCtr[:]) <= 0 {
   901  		err = errors.New("otr: counter regressed")
   902  		return
   903  	}
   904  	copy(slot.theirLastCtr[:], counter)
   905  
   906  	var iv [aes.BlockSize]byte
   907  	copy(iv[:], counter)
   908  	aesCipher, err := aes.NewCipher(slot.recvAESKey)
   909  	if err != nil {
   910  		panic(err.Error())
   911  	}
   912  	ctr := cipher.NewCTR(aesCipher, iv[:])
   913  	ctr.XORKeyStream(encrypted, encrypted)
   914  	decrypted := encrypted
   915  
   916  	if myKeyId == c.myKeyId {
   917  		c.rotateDHKeys()
   918  	}
   919  	if theirKeyId == c.theirKeyId {
   920  		// evict slots using their retired key id
   921  		for i := range c.keySlots {
   922  			slot := &c.keySlots[i]
   923  			if slot.used && slot.theirKeyId == theirKeyId-1 {
   924  				slot.used = false
   925  				c.oldMACs = append(c.oldMACs, slot.recvMACKey...)
   926  			}
   927  		}
   928  
   929  		c.theirLastDHPub = c.theirCurrentDHPub
   930  		c.theirKeyId++
   931  		c.theirCurrentDHPub = y
   932  	}
   933  
   934  	if nulPos := bytes.IndexByte(decrypted, 0); nulPos >= 0 {
   935  		out = decrypted[:nulPos]
   936  		tlvData := decrypted[nulPos+1:]
   937  		for len(tlvData) > 0 {
   938  			var t tlv
   939  			var ok1, ok2, ok3 bool
   940  
   941  			t.typ, tlvData, ok1 = getU16(tlvData)
   942  			t.length, tlvData, ok2 = getU16(tlvData)
   943  			t.data, tlvData, ok3 = getNBytes(tlvData, int(t.length))
   944  			if !ok1 || !ok2 || !ok3 {
   945  				err = errors.New("otr: corrupt tlv data")
   946  			}
   947  			tlvs = append(tlvs, t)
   948  		}
   949  	} else {
   950  		out = decrypted
   951  	}
   952  
   953  	return
   954  }
   955  
   956  func (c *Conversation) generateData(msg []byte, extra *tlv) []byte {
   957  	slot, err := c.calcDataKeys(c.myKeyId-1, c.theirKeyId)
   958  	if err != nil {
   959  		panic("otr: failed to generate sending keys: " + err.Error())
   960  	}
   961  
   962  	var plaintext []byte
   963  	plaintext = append(plaintext, msg...)
   964  	plaintext = append(plaintext, 0)
   965  
   966  	padding := paddingGranularity - ((len(plaintext) + 4) % paddingGranularity)
   967  	plaintext = appendU16(plaintext, tlvTypePadding)
   968  	plaintext = appendU16(plaintext, uint16(padding))
   969  	for i := 0; i < padding; i++ {
   970  		plaintext = append(plaintext, 0)
   971  	}
   972  
   973  	if extra != nil {
   974  		plaintext = appendU16(plaintext, extra.typ)
   975  		plaintext = appendU16(plaintext, uint16(len(extra.data)))
   976  		plaintext = append(plaintext, extra.data...)
   977  	}
   978  
   979  	encrypted := make([]byte, len(plaintext))
   980  
   981  	var iv [aes.BlockSize]byte
   982  	copy(iv[:], c.myCounter[:])
   983  	aesCipher, err := aes.NewCipher(slot.sendAESKey)
   984  	if err != nil {
   985  		panic(err.Error())
   986  	}
   987  	ctr := cipher.NewCTR(aesCipher, iv[:])
   988  	ctr.XORKeyStream(encrypted, plaintext)
   989  
   990  	var ret []byte
   991  	ret = appendU16(ret, 2)
   992  	ret = append(ret, msgTypeData)
   993  	ret = append(ret, 0 /* flags */)
   994  	ret = appendU32(ret, c.myKeyId-1)
   995  	ret = appendU32(ret, c.theirKeyId)
   996  	ret = appendMPI(ret, c.myCurrentDHPub)
   997  	ret = append(ret, c.myCounter[:]...)
   998  	ret = appendData(ret, encrypted)
   999  
  1000  	mac := hmac.New(sha1.New, slot.sendMACKey)
  1001  	mac.Write(ret)
  1002  	ret = append(ret, mac.Sum(nil)[:macPrefixBytes]...)
  1003  	ret = appendData(ret, c.oldMACs)
  1004  	c.oldMACs = nil
  1005  	incCounter(&c.myCounter)
  1006  
  1007  	return ret
  1008  }
  1009  
  1010  func incCounter(counter *[8]byte) {
  1011  	for i := 7; i >= 0; i-- {
  1012  		counter[i]++
  1013  		if counter[i] > 0 {
  1014  			break
  1015  		}
  1016  	}
  1017  }
  1018  
  1019  // calcDataKeys computes the keys used to encrypt a data message given the key
  1020  // IDs.
  1021  func (c *Conversation) calcDataKeys(myKeyId, theirKeyId uint32) (slot *keySlot, err error) {
  1022  	// Check for a cache hit.
  1023  	for i := range c.keySlots {
  1024  		slot = &c.keySlots[i]
  1025  		if slot.used && slot.theirKeyId == theirKeyId && slot.myKeyId == myKeyId {
  1026  			return
  1027  		}
  1028  	}
  1029  
  1030  	// Find an empty slot to write into.
  1031  	slot = nil
  1032  	for i := range c.keySlots {
  1033  		if !c.keySlots[i].used {
  1034  			slot = &c.keySlots[i]
  1035  			break
  1036  		}
  1037  	}
  1038  	if slot == nil {
  1039  		return nil, errors.New("otr: internal error: no more key slots")
  1040  	}
  1041  
  1042  	var myPriv, myPub, theirPub *big.Int
  1043  
  1044  	if myKeyId == c.myKeyId {
  1045  		myPriv = c.myCurrentDHPriv
  1046  		myPub = c.myCurrentDHPub
  1047  	} else if myKeyId == c.myKeyId-1 {
  1048  		myPriv = c.myLastDHPriv
  1049  		myPub = c.myLastDHPub
  1050  	} else {
  1051  		err = errors.New("otr: peer requested keyid " + strconv.FormatUint(uint64(myKeyId), 10) + " when I'm on " + strconv.FormatUint(uint64(c.myKeyId), 10))
  1052  		return
  1053  	}
  1054  
  1055  	if theirKeyId == c.theirKeyId {
  1056  		theirPub = c.theirCurrentDHPub
  1057  	} else if theirKeyId == c.theirKeyId-1 && c.theirLastDHPub != nil {
  1058  		theirPub = c.theirLastDHPub
  1059  	} else {
  1060  		err = errors.New("otr: peer requested keyid " + strconv.FormatUint(uint64(myKeyId), 10) + " when they're on " + strconv.FormatUint(uint64(c.myKeyId), 10))
  1061  		return
  1062  	}
  1063  
  1064  	var sendPrefixByte, recvPrefixByte [1]byte
  1065  
  1066  	if myPub.Cmp(theirPub) > 0 {
  1067  		// we're the high end
  1068  		sendPrefixByte[0], recvPrefixByte[0] = 1, 2
  1069  	} else {
  1070  		// we're the low end
  1071  		sendPrefixByte[0], recvPrefixByte[0] = 2, 1
  1072  	}
  1073  
  1074  	s := new(big.Int).Exp(theirPub, myPriv, p)
  1075  	sBytes := appendMPI(nil, s)
  1076  
  1077  	h := sha1.New()
  1078  	h.Write(sendPrefixByte[:])
  1079  	h.Write(sBytes)
  1080  	slot.sendAESKey = h.Sum(slot.sendAESKey[:0])[:16]
  1081  
  1082  	h.Reset()
  1083  	h.Write(slot.sendAESKey)
  1084  	slot.sendMACKey = h.Sum(slot.sendMACKey[:0])
  1085  
  1086  	h.Reset()
  1087  	h.Write(recvPrefixByte[:])
  1088  	h.Write(sBytes)
  1089  	slot.recvAESKey = h.Sum(slot.recvAESKey[:0])[:16]
  1090  
  1091  	h.Reset()
  1092  	h.Write(slot.recvAESKey)
  1093  	slot.recvMACKey = h.Sum(slot.recvMACKey[:0])
  1094  
  1095  	slot.theirKeyId = theirKeyId
  1096  	slot.myKeyId = myKeyId
  1097  	slot.used = true
  1098  
  1099  	zero(slot.theirLastCtr[:])
  1100  	return
  1101  }
  1102  
  1103  func (c *Conversation) calcAKEKeys(s *big.Int) {
  1104  	mpi := appendMPI(nil, s)
  1105  	h := sha256.New()
  1106  
  1107  	var cBytes [32]byte
  1108  	hashWithPrefix(c.SSID[:], 0, mpi, h)
  1109  
  1110  	hashWithPrefix(cBytes[:], 1, mpi, h)
  1111  	copy(c.revealKeys.c[:], cBytes[:16])
  1112  	copy(c.sigKeys.c[:], cBytes[16:])
  1113  
  1114  	hashWithPrefix(c.revealKeys.m1[:], 2, mpi, h)
  1115  	hashWithPrefix(c.revealKeys.m2[:], 3, mpi, h)
  1116  	hashWithPrefix(c.sigKeys.m1[:], 4, mpi, h)
  1117  	hashWithPrefix(c.sigKeys.m2[:], 5, mpi, h)
  1118  }
  1119  
  1120  func hashWithPrefix(out []byte, prefix byte, in []byte, h hash.Hash) {
  1121  	h.Reset()
  1122  	var p [1]byte
  1123  	p[0] = prefix
  1124  	h.Write(p[:])
  1125  	h.Write(in)
  1126  	if len(out) == h.Size() {
  1127  		h.Sum(out[:0])
  1128  	} else {
  1129  		digest := h.Sum(nil)
  1130  		copy(out, digest)
  1131  	}
  1132  }
  1133  
  1134  func (c *Conversation) encode(msg []byte) [][]byte {
  1135  	b64 := make([]byte, base64.StdEncoding.EncodedLen(len(msg))+len(msgPrefix)+1)
  1136  	base64.StdEncoding.Encode(b64[len(msgPrefix):], msg)
  1137  	copy(b64, msgPrefix)
  1138  	b64[len(b64)-1] = '.'
  1139  
  1140  	if c.FragmentSize < minFragmentSize || len(b64) <= c.FragmentSize {
  1141  		// We can encode this in a single fragment.
  1142  		return [][]byte{b64}
  1143  	}
  1144  
  1145  	// We have to fragment this message.
  1146  	var ret [][]byte
  1147  	bytesPerFragment := c.FragmentSize - minFragmentSize
  1148  	numFragments := (len(b64) + bytesPerFragment) / bytesPerFragment
  1149  
  1150  	for i := 0; i < numFragments; i++ {
  1151  		frag := []byte("?OTR," + strconv.Itoa(i+1) + "," + strconv.Itoa(numFragments) + ",")
  1152  		todo := bytesPerFragment
  1153  		if todo > len(b64) {
  1154  			todo = len(b64)
  1155  		}
  1156  		frag = append(frag, b64[:todo]...)
  1157  		b64 = b64[todo:]
  1158  		frag = append(frag, ',')
  1159  		ret = append(ret, frag)
  1160  	}
  1161  
  1162  	return ret
  1163  }
  1164  
  1165  func (c *Conversation) reset() {
  1166  	c.myKeyId = 0
  1167  
  1168  	for i := range c.keySlots {
  1169  		c.keySlots[i].used = false
  1170  	}
  1171  }
  1172  
  1173  type PublicKey struct {
  1174  	dsa.PublicKey
  1175  }
  1176  
  1177  func (pk *PublicKey) Parse(in []byte) ([]byte, bool) {
  1178  	var ok bool
  1179  	var pubKeyType uint16
  1180  
  1181  	if pubKeyType, in, ok = getU16(in); !ok || pubKeyType != 0 {
  1182  		return nil, false
  1183  	}
  1184  	if pk.P, in, ok = getMPI(in); !ok {
  1185  		return nil, false
  1186  	}
  1187  	if pk.Q, in, ok = getMPI(in); !ok {
  1188  		return nil, false
  1189  	}
  1190  	if pk.G, in, ok = getMPI(in); !ok {
  1191  		return nil, false
  1192  	}
  1193  	if pk.Y, in, ok = getMPI(in); !ok {
  1194  		return nil, false
  1195  	}
  1196  
  1197  	return in, true
  1198  }
  1199  
  1200  func (pk *PublicKey) Serialize(in []byte) []byte {
  1201  	in = appendU16(in, 0)
  1202  	in = appendMPI(in, pk.P)
  1203  	in = appendMPI(in, pk.Q)
  1204  	in = appendMPI(in, pk.G)
  1205  	in = appendMPI(in, pk.Y)
  1206  	return in
  1207  }
  1208  
  1209  // Fingerprint returns the 20-byte, binary fingerprint of the PublicKey.
  1210  func (pk *PublicKey) Fingerprint() []byte {
  1211  	b := pk.Serialize(nil)
  1212  	h := sha1.New()
  1213  	h.Write(b[2:])
  1214  	return h.Sum(nil)
  1215  }
  1216  
  1217  func (pk *PublicKey) Verify(hashed, sig []byte) ([]byte, bool) {
  1218  	if len(sig) != 2*dsaSubgroupBytes {
  1219  		return nil, false
  1220  	}
  1221  	r := new(big.Int).SetBytes(sig[:dsaSubgroupBytes])
  1222  	s := new(big.Int).SetBytes(sig[dsaSubgroupBytes:])
  1223  	ok := dsa.Verify(&pk.PublicKey, hashed, r, s)
  1224  	return sig[dsaSubgroupBytes*2:], ok
  1225  }
  1226  
  1227  type PrivateKey struct {
  1228  	PublicKey
  1229  	dsa.PrivateKey
  1230  }
  1231  
  1232  func (priv *PrivateKey) Sign(rand io.Reader, hashed []byte) []byte {
  1233  	r, s, err := dsa.Sign(rand, &priv.PrivateKey, hashed)
  1234  	if err != nil {
  1235  		panic(err.Error())
  1236  	}
  1237  	rBytes := r.Bytes()
  1238  	sBytes := s.Bytes()
  1239  	if len(rBytes) > dsaSubgroupBytes || len(sBytes) > dsaSubgroupBytes {
  1240  		panic("DSA signature too large")
  1241  	}
  1242  
  1243  	out := make([]byte, 2*dsaSubgroupBytes)
  1244  	copy(out[dsaSubgroupBytes-len(rBytes):], rBytes)
  1245  	copy(out[len(out)-len(sBytes):], sBytes)
  1246  	return out
  1247  }
  1248  
  1249  func (priv *PrivateKey) Serialize(in []byte) []byte {
  1250  	in = priv.PublicKey.Serialize(in)
  1251  	in = appendMPI(in, priv.PrivateKey.X)
  1252  	return in
  1253  }
  1254  
  1255  func (priv *PrivateKey) Parse(in []byte) ([]byte, bool) {
  1256  	in, ok := priv.PublicKey.Parse(in)
  1257  	if !ok {
  1258  		return in, ok
  1259  	}
  1260  	priv.PrivateKey.PublicKey = priv.PublicKey.PublicKey
  1261  	priv.PrivateKey.X, in, ok = getMPI(in)
  1262  	return in, ok
  1263  }
  1264  
  1265  func (priv *PrivateKey) Generate(rand io.Reader) {
  1266  	if err := dsa.GenerateParameters(&priv.PrivateKey.PublicKey.Parameters, rand, dsa.L1024N160); err != nil {
  1267  		panic(err.Error())
  1268  	}
  1269  	if err := dsa.GenerateKey(&priv.PrivateKey, rand); err != nil {
  1270  		panic(err.Error())
  1271  	}
  1272  	priv.PublicKey.PublicKey = priv.PrivateKey.PublicKey
  1273  }
  1274  
  1275  func notHex(r rune) bool {
  1276  	if r >= '0' && r <= '9' ||
  1277  		r >= 'a' && r <= 'f' ||
  1278  		r >= 'A' && r <= 'F' {
  1279  		return false
  1280  	}
  1281  
  1282  	return true
  1283  }
  1284  
  1285  // Import parses the contents of a libotr private key file.
  1286  func (priv *PrivateKey) Import(in []byte) bool {
  1287  	mpiStart := []byte(" #")
  1288  
  1289  	mpis := make([]*big.Int, 5)
  1290  
  1291  	for i := 0; i < len(mpis); i++ {
  1292  		start := bytes.Index(in, mpiStart)
  1293  		if start == -1 {
  1294  			return false
  1295  		}
  1296  		in = in[start+len(mpiStart):]
  1297  		end := bytes.IndexFunc(in, notHex)
  1298  		if end == -1 {
  1299  			return false
  1300  		}
  1301  		hexBytes := in[:end]
  1302  		in = in[end:]
  1303  
  1304  		if len(hexBytes)&1 != 0 {
  1305  			return false
  1306  		}
  1307  
  1308  		mpiBytes := make([]byte, len(hexBytes)/2)
  1309  		if _, err := hex.Decode(mpiBytes, hexBytes); err != nil {
  1310  			return false
  1311  		}
  1312  
  1313  		mpis[i] = new(big.Int).SetBytes(mpiBytes)
  1314  	}
  1315  
  1316  	priv.PrivateKey.P = mpis[0]
  1317  	priv.PrivateKey.Q = mpis[1]
  1318  	priv.PrivateKey.G = mpis[2]
  1319  	priv.PrivateKey.Y = mpis[3]
  1320  	priv.PrivateKey.X = mpis[4]
  1321  	priv.PublicKey.PublicKey = priv.PrivateKey.PublicKey
  1322  
  1323  	a := new(big.Int).Exp(priv.PrivateKey.G, priv.PrivateKey.X, priv.PrivateKey.P)
  1324  	return a.Cmp(priv.PrivateKey.Y) == 0
  1325  }
  1326  
  1327  func getU8(in []byte) (uint8, []byte, bool) {
  1328  	if len(in) < 1 {
  1329  		return 0, in, false
  1330  	}
  1331  	return in[0], in[1:], true
  1332  }
  1333  
  1334  func getU16(in []byte) (uint16, []byte, bool) {
  1335  	if len(in) < 2 {
  1336  		return 0, in, false
  1337  	}
  1338  	r := uint16(in[0])<<8 | uint16(in[1])
  1339  	return r, in[2:], true
  1340  }
  1341  
  1342  func getU32(in []byte) (uint32, []byte, bool) {
  1343  	if len(in) < 4 {
  1344  		return 0, in, false
  1345  	}
  1346  	r := uint32(in[0])<<24 | uint32(in[1])<<16 | uint32(in[2])<<8 | uint32(in[3])
  1347  	return r, in[4:], true
  1348  }
  1349  
  1350  func getMPI(in []byte) (*big.Int, []byte, bool) {
  1351  	l, in, ok := getU32(in)
  1352  	if !ok || uint32(len(in)) < l {
  1353  		return nil, in, false
  1354  	}
  1355  	r := new(big.Int).SetBytes(in[:l])
  1356  	return r, in[l:], true
  1357  }
  1358  
  1359  func getData(in []byte) ([]byte, []byte, bool) {
  1360  	l, in, ok := getU32(in)
  1361  	if !ok || uint32(len(in)) < l {
  1362  		return nil, in, false
  1363  	}
  1364  	return in[:l], in[l:], true
  1365  }
  1366  
  1367  func getNBytes(in []byte, n int) ([]byte, []byte, bool) {
  1368  	if len(in) < n {
  1369  		return nil, in, false
  1370  	}
  1371  	return in[:n], in[n:], true
  1372  }
  1373  
  1374  func appendU16(out []byte, v uint16) []byte {
  1375  	out = append(out, byte(v>>8), byte(v))
  1376  	return out
  1377  }
  1378  
  1379  func appendU32(out []byte, v uint32) []byte {
  1380  	out = append(out, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
  1381  	return out
  1382  }
  1383  
  1384  func appendData(out, v []byte) []byte {
  1385  	out = appendU32(out, uint32(len(v)))
  1386  	out = append(out, v...)
  1387  	return out
  1388  }
  1389  
  1390  func appendMPI(out []byte, v *big.Int) []byte {
  1391  	vBytes := v.Bytes()
  1392  	out = appendU32(out, uint32(len(vBytes)))
  1393  	out = append(out, vBytes...)
  1394  	return out
  1395  }
  1396  
  1397  func appendMPIs(out []byte, mpis ...*big.Int) []byte {
  1398  	for _, mpi := range mpis {
  1399  		out = appendMPI(out, mpi)
  1400  	}
  1401  	return out
  1402  }
  1403  
  1404  func zero(b []byte) {
  1405  	for i := range b {
  1406  		b[i] = 0
  1407  	}
  1408  }