...

Source file src/golang.org/x/crypto/otr/otr.go

Documentation: golang.org/x/crypto/otr

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

View as plain text