/** * Set a timestamp and calculate a digital signature. First * calculate the SHA1 hash of the pubKey, title, timestamp, * and content lines, excluding the terminating CRLF in each * case, then encrypt that using the RSA private key supplied. * * @param key RSAKey whose secret materials are used to sign */ func (sl *SignedBList) Sign(skPriv *rsa.PrivateKey) (err error) { var ( digSig, hash []byte ) if sl.DigSig != nil { err = ListAlreadySigned } else if skPriv == nil { err = NilPrivateKey } else { sl.Timestamp = xu.Timestamp(time.Now().UnixNano()) hash, err = sl.HashBody() if err == nil { digSig, err = rsa.SignPKCS1v15( rand.Reader, skPriv, crypto.SHA1, hash) if err == nil { sl.DigSig = digSig } } if err != nil { sl.Timestamp = 0 // restore to default } } return }
func (s *XLSuite) TestChunkList(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_CHUNK_LIST") } rng := xr.MakeSimpleRNG() dataLen := 1 + rng.Intn(3*MAX_DATA_BYTES) data := make([]byte, dataLen) rng.NextBytes(data) reader := bytes.NewReader(data) d := sha1.New() d.Write(data) datum := d.Sum(nil) nodeID, err := xi.NewNodeID(datum) c.Assert(err, IsNil) skPriv, err := rsa.GenerateKey(rand.Reader, 1024) // cheap key sk := &skPriv.PublicKey title := rng.NextFileName(8) timestamp := xu.Timestamp(rng.Int63()) cl, err := NewChunkList(sk, title, timestamp, reader, int64(dataLen), datum, nil) c.Assert(err, IsNil) c.Assert(cl, NotNil) chunkCount := uint((dataLen + MAX_DATA_BYTES - 1) / MAX_DATA_BYTES) c.Assert(cl.Size(), Equals, chunkCount) for i := uint(0); i < chunkCount; i++ { actual, err := cl.HashItem(i) c.Assert(err, IsNil) expected := s.calculateChunkHash(c, i, datum, data) // DEBUG fmt.Printf("chunk %d hash\n actual %x\n expected %x\n", i, actual, expected) // END //c.Assert(actual, DeepEquals, expected) // compare with result of calculation in NewChunk ----------- var chunk *Chunk var slice []byte if i == chunkCount-1 { slice = data[i*MAX_DATA_BYTES:] } else { slice = data[i*MAX_DATA_BYTES : (i+1)*MAX_DATA_BYTES] } chunk, err = NewChunk(nodeID, uint32(i), slice) c.Assert(err, Equals, nil) c.Assert(chunk.GetChunkHash(), DeepEquals, expected) } }
func (s *XLSuite) TestChunkListAssyDisassy(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_CHUNK_LIST_ASSY_DISASSY") } rng := xr.MakeSimpleRNG() // make a slice 3 to 7 chunks long, fill with random-ish data --- chunkCount := 3 + rng.Intn(5) // so 3 to 7, inclusive lastChunkLen := 1 + rng.Intn(MAX_DATA_BYTES-1) dataLen := (chunkCount-1)*MAX_DATA_BYTES + lastChunkLen data := make([]byte, dataLen) rng.NextBytes(data) // calculate datum, the SHA hash of the data -------------------- //d := sha3.NewKeccak256() d := sha1.New() d.Write(data) hash := d.Sum(nil) datum, err := xi.NewNodeID(hash) c.Assert(err, IsNil) // create tmp if it doesn't exist ------------------------------- found, err := xf.PathExists("tmp") c.Assert(err, IsNil) if !found { err = os.MkdirAll("tmp", 0755) c.Assert(err, IsNil) } // create scratch subdir with unique name ----------------------- var pathToU string for { dirName := rng.NextFileName(8) pathToU = path.Join("tmp", dirName) found, err = xf.PathExists(pathToU) c.Assert(err, IsNil) if !found { break } } // create a FLAT uDir at that point ----------------------------- myU, err := u.New(pathToU, u.DIR_FLAT, 0) // 0 means default perm c.Assert(err, IsNil) // write the test data into uDir -------------------------------- bytesWritten, key, err := myU.PutData(data, datum.Value()) c.Assert(err, IsNil) c.Assert(bytes.Equal(datum.Value(), key), Equals, true) c.Assert(bytesWritten, Equals, int64(dataLen)) skPriv, err := rsa.GenerateKey(rand.Reader, 1024) // cheap key sk := &skPriv.PublicKey c.Assert(err, IsNil) c.Assert(skPriv, NotNil) // Verify the file is present in uDir --------------------------- // (yes this is a test of uDir logic but these are early days --- // XXX uDir.Exist(arg) - arg should be []byte, no string keyStr := hex.EncodeToString(key) found, err = myU.HexKeyExists(keyStr) c.Assert(err, IsNil) c.Assert(found, Equals, true) // use the data file to build a chunkList, writing the chunks --- title := rng.NextFileName(8) now := xu.Timestamp(time.Now().UnixNano()) // make a reader -------------------------------------- pathToData, err := myU.GetPathForHexKey(keyStr) c.Assert(err, IsNil) reader, err := os.Open(pathToData) // open for read only c.Assert(err, IsNil) defer reader.Close() chunkList, err := NewChunkList(sk, title, now, reader, int64(dataLen), key, myU) c.Assert(err, IsNil) err = chunkList.Sign(skPriv) c.Assert(err, IsNil) digSig, err := chunkList.GetDigSig() c.Assert(err, IsNil) c.Assert(bytes.Equal(digSig, chunkList.digSig), Equals, true) err = chunkList.Verify() c.Assert(err, IsNil) // REBUILD AND CHECK -------------------------------------------- // rebuild the complete file from the chunkList and files present // in myU u2, err := u.New(pathToU, u.DIR_FLAT, 0) // 0 means default perm c.Assert(err, IsNil) var data2 []byte // should become copy of original count := chunkList.Size() for i := uint(0); i < count; i++ { chunkHash, err := chunkList.HashItem(i) c.Assert(err, IsNil) c.Assert(chunkHash, NotNil) var raw []byte // THIS IS A CHUNK, and so has a header, possibly some // padding, and then its own hash :-). Need to verify // and discard the last, then drop the padding. // CORRECTION: hash should NOT have been written to disk raw, err = u2.GetData(chunkHash) c.Assert(err, IsNil) chunk := &Chunk{packet: raw} ndx := chunk.GetIndex() c.Assert(ndx, Equals, uint32(i)) rawLen := uint32(len(raw)) dataLen := chunk.GetDataLen() //fmt.Printf("chunk %2d: index is %8d\n", i, ndx) //fmt.Printf(" len raw is %6d (%4x)\n", rawLen, rawLen) //fmt.Printf(" dataLen is %6d (%4x)\n", dataLen, dataLen) // if this isn't true, we get a panic c.Assert(dataLen < rawLen, Equals, true) payload := chunk.GetData() data2 = append(data2, payload...) } // verify that the content key of the rebuilt file is identical to // that of the original //d2D := sha3.NewKeccak256() d2D := sha1.New() d2D.Write(data2) hash2 := d2D.Sum(nil) datum2, err := xi.NewNodeID(hash2) c.Assert(err, IsNil) // DEBUG //fmt.Printf("datum: %x\ndatum2: %x\n", datum.Value(), datum2.Value()) //fmt.Printf("data: %x\ndata2: %x\n", data, data2) // END c.Assert(bytes.Equal(datum.Value(), datum2.Value()), Equals, true) // presumably pure pedantry: verify that the file contents are // also equal c.Assert(bytes.Equal(data, data2), Equals, true) }