func (s *XLSuite) makeEntryData(c *C, rng *xr.PRNG, whichSHA int) ( t int64, key, nodeID []byte, src, path string) { t = rng.Int63() // timestamp var length int switch whichSHA { case xu.USING_SHA1: length = xu.SHA1_BIN_LEN case xu.USING_SHA2: length = xu.SHA2_BIN_LEN case xu.USING_SHA3: length = xu.SHA3_BIN_LEN // XXX DEFAULT = ERROR } key = make([]byte, length) rng.NextBytes(key) nodeID = make([]byte, length) rng.NextBytes(nodeID) src = rng.NextFileName(32) // 32 is max len path = rng.NextFileName(32) for strings.Contains(path, ".") { // that crude fix path = rng.NextFileName(32) } return }
func (s *XLSuite) doTestMDParser(c *C, rng *xr.PRNG, whichSHA int) { var tHash []byte switch whichSHA { case xu.USING_SHA1: tHash = make([]byte, xu.SHA1_BIN_LEN) case xu.USING_SHA2: tHash = make([]byte, xu.SHA2_BIN_LEN) case xu.USING_SHA3: tHash = make([]byte, xu.SHA3_BIN_LEN) // DEFAULT = ERROR } rng.NextBytes(tHash) // not really a hash, of course sHash := hex.EncodeToString(tHash) // string form of tHash withoutSlash := rng.NextFileName(8) dirName := withoutSlash + "/" length := rng.Intn(4) var rSpaces string for i := 0; i < length; i++ { rSpaces += " " // on the right } // TEST FIRST LINE PARSER ----------------------------- line := sHash + " " + dirName + rSpaces treeHash2, dirName2, err := ParseMerkleDocFirstLine(line) c.Assert(err, IsNil) c.Assert(bytes.Equal(treeHash2, tHash), Equals, true) // we retain the terminating slash in MerkleDoc first lines c.Assert(dirName2, Equals, dirName) }
// Create an AES IV and key and an 8-byte salt, then encrypt these and // the proposed protocol version using the server's comms public key. func ClientEncryptHello(version1 uint32, ck *rsa.PublicKey, rng *xr.PRNG) ( cOneShot *AesSession, ciphertext []byte, err error) { if rng == nil { rng = xr.MakeSystemRNG() } vBytes := make([]byte, 4) vBytes[0] = byte(version1) vBytes[1] = byte(version1 >> 8) vBytes[2] = byte(version1 >> 16) vBytes[3] = byte(version1 >> 24) // Generate 32-byte AES key, and 8-byte salt for the Hello salty := make([]byte, 2*aes.BlockSize+8+20) rng.NextBytes(salty) key1 := salty[:2*aes.BlockSize] // salt1 := salty[2*aes.BlockSize : 2*aes.BlockSize+8] oaep1 := salty[2*aes.BlockSize+8:] oaepSalt := bytes.NewBuffer(oaep1) sha := sha1.New() data := salty[:2*aes.BlockSize+8] // contains key1,salt1 data = append(data, vBytes...) // ... plus preferred protocol version ciphertext, err = rsa.EncryptOAEP(sha, oaepSalt, ck, data, nil) if err == nil { cOneShot, err = NewAesSession(key1, rng) } return }
// Make a message (or reply) of up to 16 AES blocks in size and stuff // it with random bytes. Return the message with PKCS7-padded appended. // func (s *XLSuite) MakeAMsg(c *C, rng *xr.PRNG) ( msg []byte, msgLen int) { msgLen = 2 + rng.Intn(16*aes.BlockSize-2) msg = make([]byte, msgLen) rng.NextBytes(msg) return }
func makeNodeID(rng *xr.PRNG) (*xi.NodeID, error) { var buffer []byte // quasi-random choice, whether to use an SHA1 or SHA3 nodeID if rng.NextBoolean() { buffer = make([]byte, xu.SHA1_BIN_LEN) } else { buffer = make([]byte, xu.SHA3_BIN_LEN) } rng.NextBytes(buffer) return xi.NewNodeID(buffer) }
func (s *XLSuite) makeANodeID(c *C, rng *xr.PRNG) (id *NodeID) { var length int if rng.NextBoolean() { length = xu.SHA1_BIN_LEN } else { length = xu.SHA2_BIN_LEN } data := make([]byte, length) rng.NextBytes(data) id, err := New(data) c.Assert(err, IsNil) return id }
// Populate the K3 byte slices to be used for testing func (muc *MockUpaxClient) createData(rng *xr.PRNG, K3, L1, L2 int) ( err error) { muc.K3 = K3 muc.L1 = L1 muc.L2 = L2 muc.data = make([][]byte, K3) for i := 0; i < K3; i++ { length := L1 + rng.Intn(L2-L1+1) // so L1..L2 inclusive muc.data[i] = make([]byte, length) rng.NextBytes(muc.data[i]) } return }
// PARSER TESTS ===================================================== func (s *XLSuite) doTestParser(c *C, rng *xr.PRNG, whichSHA int) { var tHash []byte switch whichSHA { case xu.USING_SHA1: tHash = make([]byte, xu.SHA1_BIN_LEN) case xu.USING_SHA2: tHash = make([]byte, xu.SHA2_BIN_LEN) case xu.USING_SHA3: tHash = make([]byte, xu.SHA3_BIN_LEN) // XXX DEFAULT = ERROR } rng.NextBytes(tHash) // not really a hash, of course sHash := hex.EncodeToString(tHash) // string form of tHash dirName := rng.NextFileName(8) + "/" nameWithoutSlash := dirName[0 : len(dirName)-1] indent := rng.Intn(4) var lSpaces, rSpaces string for i := 0; i < indent; i++ { lSpaces += " " // on the left rSpaces += " " // on the right } // TEST FIRST LINE PARSER ----------------------------- line := lSpaces + sHash + " " + dirName + rSpaces indent2, treeHash2, dirName2, err := ParseFirstLine(line, " ") c.Assert(err, IsNil) c.Assert(indent2, Equals, indent) c.Assert(bytes.Equal(treeHash2, tHash), Equals, true) c.Assert(dirName2, Equals, nameWithoutSlash) // TEST OTHER LINE PARSER ----------------------------- yesIsDir := rng.NextBoolean() if yesIsDir { line = lSpaces + sHash + " " + dirName + rSpaces } else { line = lSpaces + sHash + " " + nameWithoutSlash + rSpaces } nodeDepth, nodeHash, nodeName, isDir, err := ParseOtherLine(line, " ") c.Assert(err, IsNil) c.Assert(nodeDepth, Equals, indent) c.Assert(bytes.Equal(nodeHash, tHash), Equals, true) c.Assert(nodeName, Equals, nameWithoutSlash) c.Assert(isDir, Equals, yesIsDir) }
func (s *XLSuite) uniqueKeyMaker(c *C, rng *xr.PRNG, w, keyCount, keyLen uint) ( rawKeys [][]byte, bKeys []BytesKey, hashcodes []uint64, values []interface{}) { maxCount := uint(1 << w) if keyCount > maxCount { msg := fmt.Sprintf( "too few bits in %d: cannot guarantee uniqueness of %d keys", w, keyCount) panic(msg) } flag := uint64(1 << w) mask := flag - 1 rawKeys = make([][]byte, keyCount) bKeys = make([]BytesKey, keyCount) hashcodes = make([]uint64, keyCount) values = make([]interface{}, keyCount) ndxMap := make(map[uint64]bool) // Build keyCount rawKeys of length keyLen, using the masked hashcode to // guarantee uniqueness. for i := uint(0); i < keyCount; i++ { var hc uint64 key := make([]byte, keyLen) for { rng.NextBytes(key) // fill with quasi-random values rawKeys[i] = key bKey, err := NewBytesKey(key) c.Assert(err, IsNil) c.Assert(bKey, NotNil) bKeys[i] = bKey hc = bKey.Hashcode() ndx := hc & mask _, ok := ndxMap[ndx] if !ok { ndxMap[ndx] = true break } } values[i] = &key hashcodes[i] = hc } return }
func (s *XLSuite) checkOneMessage(c *C, rng *xr.PRNG, size int) { msg := make([]byte, size) rng.NextBytes(msg) iv := s.makeAESIV(rng) key := s.makeAESKey(rng) // padding ------------------------------------------------------ padded, err := AddPKCS7Padding(msg, aes.BlockSize) c.Assert(err, IsNil) paddedLen := len(padded) // it's been padded to block size nBlocks := paddedLen / aes.BlockSize c.Assert(nBlocks*aes.BlockSize, Equals, paddedLen) // encryption --------------------------------------------------- cryptoLen := paddedLen ciphertext := make([]byte, cryptoLen) engineA, err := aes.NewCipher(key) // cipher.Block c.Assert(err, IsNil) encrypterA := cipher.NewCBCEncrypter(engineA, iv) encrypterA.CryptBlocks(ciphertext, padded) // dest <- src // decryption --------------------------------------------------- plaintext := make([]byte, paddedLen) engineB, err := aes.NewCipher(key) // cipher.Block c.Assert(err, IsNil) decrypterB := cipher.NewCBCDecrypter(engineB, iv) decrypterB.CryptBlocks(plaintext, ciphertext) // dest <- src c.Assert(bytes.Equal(plaintext, padded), Equals, true) // FAILS XXX // unpadding ---------------------------------------------------- reply, err := StripPKCS7Padding(plaintext, aes.BlockSize) c.Assert(err, IsNil) c.Assert(bytes.Equal(reply, msg), Equals, true) }
func (s *XLSuite) doTestAesSession(c *C, rng *xr.PRNG) { // SESSION SETUP ================================================ // A->B half circuit ---------------------------------- keyAB := make([]byte, 2*aes.BlockSize) rng.NextBytes(keyAB) // set up A side of A->B half-circuit hAOut, err := NewAesSession(keyAB, rng) c.Assert(err, IsNil) c.Assert(hAOut.Engine, NotNil) // set up B side of A->B half-circuit hBIn, err := NewAesSession(keyAB, rng) c.Assert(err, IsNil) c.Assert(hBIn.Engine, NotNil) // B->A half circuit ---------------------------------- keyBA := make([]byte, 2*aes.BlockSize) rng.NextBytes(keyBA) // set up B side of B->A half-circuit hBOut, err := NewAesSession(keyBA, rng) c.Assert(err, IsNil) c.Assert(hBOut.Engine, NotNil) // set up A side of B->A half-circuit hAIn, err := NewAesSession(keyBA, rng) c.Assert(err, IsNil) c.Assert(hAIn.Engine, NotNil) // for N messages initiated by A N := 4 for n := 0; n < N; n++ { // A create a random-ish message ---------------------------- msg, msgSize := s.MakeAMsg(c, rng) // encrypt it, yielding abCiphertext, which is prefixed with the IV abCiphertext, err := hAOut.Encrypt(msg) c.Assert(err, IsNil) ivA := abCiphertext[0:aes.BlockSize] // B decrypts msg ----------------------------------------- unpaddedMsg, err := hBIn.Decrypt(abCiphertext) c.Assert(err, IsNil) ivAb := abCiphertext[0:aes.BlockSize] c.Assert(ivAb, DeepEquals, ivA) c.Assert(len(unpaddedMsg), Equals, msgSize) c.Assert(unpaddedMsg, DeepEquals, msg) // B create a random-ish message ---------------------------- reply, replySize := s.MakeAMsg(c, rng) // encrypt it, yielding baCiphertext, which is prefixed with the IV baCiphertext, err := hBOut.Encrypt(reply) c.Assert(err, IsNil) ivB := baCiphertext[0:aes.BlockSize] // A decrypts reply ----------------------------------------- unpaddedReply, err := hAIn.Decrypt(baCiphertext) c.Assert(err, IsNil) ivBb := baCiphertext[0:aes.BlockSize] c.Assert(ivBb, DeepEquals, ivB) c.Assert(len(unpaddedReply), Equals, replySize) c.Assert(unpaddedReply, DeepEquals, reply) } }
func (s *XLSuite) makeAnID(c *C, rng *xr.PRNG) (id []byte) { id = make([]byte, xu.SHA1_BIN_LEN) rng.NextBytes(id) return }
func (s *XLSuite) doTestRegexes(c *C, rng *xr.PRNG, whichSHA int) { t := rng.Int63() var length int switch whichSHA { case xu.USING_SHA1: length = xu.SHA1_BIN_LEN case xu.USING_SHA2: length = xu.SHA2_BIN_LEN case xu.USING_SHA3: length = xu.SHA3_BIN_LEN // XXX DEFAULT = ERROR } key := make([]byte, length) rng.NextBytes(key) hexKey := hex.EncodeToString(key) nodeID := make([]byte, length) rng.NextBytes(nodeID) hexNodeID := hex.EncodeToString(nodeID) src := rng.NextFileName(32) // 32 is max len path := rng.NextFileName(32) for strings.Contains(path, ".") { // XXX a crude fix path = rng.NextFileName(32) } expected := fmt.Sprintf("%d %s %s \"%s\" %s", t, hexKey, hexNodeID, src, path) switch whichSHA { case xu.USING_SHA1: c.Assert(bodyLine1RE.MatchString(expected), Equals, true) groups := bodyLine1RE.FindStringSubmatch(expected) c.Assert(groups, Not(IsNil)) c.Assert(len(groups), Equals, 6) // 5 fields + match on all c.Assert(bodyLine3RE.MatchString(expected), Equals, false) case xu.USING_SHA2: c.Assert(bodyLine2RE.MatchString(expected), Equals, true) groups := bodyLine2RE.FindStringSubmatch(expected) c.Assert(groups, Not(IsNil)) c.Assert(len(groups), Equals, 6) // 5 fields + match on all c.Assert(bodyLine1RE.MatchString(expected), Equals, false) case xu.USING_SHA3: // DEBUG if !bodyLine3RE.MatchString(expected) { fmt.Printf("DOESN'T MATCH PATTERN: %s\n", expected) } // END c.Assert(bodyLine3RE.MatchString(expected), Equals, true) groups := bodyLine3RE.FindStringSubmatch(expected) c.Assert(groups, Not(IsNil)) c.Assert(len(groups), Equals, 6) c.Assert(bodyLine1RE.MatchString(expected), Equals, false) // XXX DEFAULT = ERROR } }
func (s *XLSuite) makeAESKey(rng *xr.PRNG) (iv []byte) { iv = make([]byte, 2*aes.BlockSize) rng.NextBytes(iv) return }
func (s *XLSuite) doKeyTests(c *C, node *Node, rng *xr.PRNG) { // COMMS KEY commsPubKey := node.GetCommsPublicKey() c.Assert(commsPubKey, Not(IsNil)) // NOT privCommsKey := node.GetCommsPrivateKey() c.Assert(privCommsKey.Validate(), IsNil) expLen := (*privCommsKey.D).BitLen() if VERBOSITY > 1 { fmt.Printf("bit length of comms private key exponent is %d\n", expLen) } // 2037 seen at least once c.Assert(true, Equals, (2036 <= expLen) && (expLen <= 2048)) c.Assert(privCommsKey.PublicKey, Equals, *commsPubKey) // XXX FAILS // SIG KEY sigPubKey := node.GetSigPublicKey() c.Assert(sigPubKey, Not(IsNil)) // NOT privSigKey := node.GetSigPrivateKey() c.Assert(privSigKey.Validate(), IsNil) expLen = (*privSigKey.D).BitLen() if VERBOSITY > 1 { fmt.Printf("bit length of sig private key exponent is %d\n", expLen) } // lowest value seen as of 2013-07-16 was 2039 c.Assert(true, Equals, (2036 <= expLen) && (expLen <= 2048)) c.Assert(privSigKey.PublicKey, Equals, *sigPubKey) // FOO // sign ///////////////////////////////////////////////////////// msgLen := 128 msg := make([]byte, msgLen) rng.NextBytes(msg) d := sha1.New() d.Write(msg) hash := d.Sum(nil) sig, err := rsa.SignPKCS1v15(rand.Reader, node.skPriv, cr.SHA1, hash) c.Assert(err, IsNil) signer := node.getSigner() signer.Update(msg) sig2, err := signer.Sign() // XXX change interface to allow arg lenSig := len(sig) lenSig2 := len(sig2) c.Assert(lenSig, Equals, lenSig2) for i := 0; i < lenSig; i++ { c.Assert(sig[i], Equals, sig2[i]) } // verify /////////////////////////////////////////////////////// err = rsa.VerifyPKCS1v15(sigPubKey, cr.SHA1, hash, sig) c.Assert(err, IsNil) // 2013-06-15, SigVerify now returns error, so nil means OK c.Assert(nil, Equals, xc.SigVerify(sigPubKey, msg, sig)) s.nilArgCheck(c) }