func ParseDigiListFromStrings(ss []string) ( dl *DigiList, rest []string, err error) { var ( sk *rsa.PublicKey title string t xu.Timestamp digSig []byte ) if len(ss) < 4 { err = TooShortForDigiList } if err == nil { sk, err = xc.RSAPubKeyFromDisk([]byte(ss[0])) } if err == nil { title = ss[1] t, err = xu.ParseTimestamp(ss[2]) } if err == nil { digSig, err = base64.StdEncoding.DecodeString(ss[3]) } if err == nil { dl = &DigiList{sk, title, t, digSig} rest = ss[4:] } return }
// Read the header part of a signed list that has been serialized in disk // format, returning a pointer to the deserialized object or an error. // Subclasses should call this to get a pointer to the BuildList part // of the subclass struct. If the subclass is an XXXList, then expect // the calling routine to be ParseXXXList() // func ParseUnsignedBList(in io.Reader) (uList *UnsignedBList, err error) { var ( line []byte title string t xu.Timestamp // binary form ) bin := bufio.NewReader(in) // Read the header part ----------------------------------------- line, err = xc.NextLineWithoutCRLF(bin) if err == nil { title = string(line) line, err = xc.NextLineWithoutCRLF(bin) if err == nil { t, err = xu.ParseTimestamp(string(line)) if err == nil { line, err = xc.NextLineWithoutCRLF(bin) if err == nil { if !bytes.Equal(line, xc.CONTENT_START) { err = xc.MissingContentStart } } } } } // Build and populate the SignedBList object --------------------- if err == nil { var bList *xc.BuildList bList, err = xc.NewBuildList(title, t) if err == nil { uList = &UnsignedBList{ BuildList: *bList, } // Read the content lines and then any docHash line ------ err = ReadContents(bin, uList, false) // true = is signed if err == nil { // try to read any docHash line var docHash []byte line, err = xc.NextLineWithoutCRLF(bin) if (err == nil || err == io.EOF) && (len(line) > 0) { docHash, err = base64.StdEncoding.DecodeString(string(line)) if err == nil || err == io.EOF { uList.setDocHash(docHash) if err == io.EOF { err = nil } } } } } } return }
// Read the header part of a signed list that has been serialized in disk // format, returning a pointer to the deserialized object or an error. // Subclasses should call this to get a pointer to the BuildList part // of the subclass struct. If the subclass is an XXXList, then expect // the calling routine to be ParseXXXList() // func ParseSignedBList(in io.Reader) (sList *SignedBList, err error) { var ( line []byte pubKey *rsa.PublicKey title string t xu.Timestamp // binary form ) bin := bufio.NewReader(in) // Read the header part ----------------------------------------- line, err = xc.NextLineWithoutCRLF(bin) if err == nil { title = string(line) line, err = xc.NextLineWithoutCRLF(bin) if err == nil { t, err = xu.ParseTimestamp(string(line)) if err == nil { line, err = xc.NextLineWithoutCRLF(bin) if err == nil { line = append(line, 10) // NEWLINE pubKey, err = xc.RSAPubKeyFromDisk(line) if err == nil { line, err = xc.NextLineWithoutCRLF(bin) if err == nil { if !bytes.Equal(line, xc.CONTENT_START) { err = xc.MissingContentStart } } } } } } } // Build and populate the SignedBList object --------------------- if err == nil { var bList *xc.BuildList bList, err = xc.NewBuildList(title, t) if err == nil { sList = &SignedBList{ PubKey: pubKey, BuildList: *bList, } // Read the content lines and then the dig sig ---------- err = ReadContents(bin, sList, true) // true = is signed if err == nil { // try to read the digital signature line var digSig []byte line, err = xc.NextLineWithoutCRLF(bin) if err == nil || err == io.EOF { digSig, err = base64.StdEncoding.DecodeString(string(line)) if err == nil || err == io.EOF { sList.SetDigSig(digSig) if err == io.EOF { err = nil } } } } } } return }
func (s *XLSuite) TestGeneratedUnsignedBList(c *C) { var ( err error myList *UnsignedBList ) rng := xr.MakeSimpleRNG() hash0 := make([]byte, xu.SHA1_BIN_LEN) hash1 := make([]byte, xu.SHA1_BIN_LEN) hash2 := make([]byte, xu.SHA1_BIN_LEN) hash3 := make([]byte, xu.SHA1_BIN_LEN) rng.NextBytes(hash0) rng.NextBytes(hash1) rng.NextBytes(hash2) rng.NextBytes(hash3) myList, err = NewUnsignedBList("document 1") c.Assert(err, IsNil) c.Assert(myList, NotNil) c.Assert(myList.Size(), Equals, uint(0)) c.Assert(myList.IsHashed(), Equals, false) // XXX SHOULD SET TIME to uDocTime HERE XXX t, err := xu.ParseTimestamp(uDocTime) c.Assert(err, IsNil) myList.setTimestamp(t) // XXX NOTE WE CAN ADD DUPLICATE OR CONFLICTING ITEMS !! XXX err = myList.Add(hash0, "fileForHash0") c.Assert(err, IsNil) c.Assert(myList.Size(), Equals, uint(1)) err = myList.Add(hash1, "fileForHash1") c.Assert(err, IsNil) c.Assert(myList.Size(), Equals, uint(2)) err = myList.Add(hash2, "fileForHash2") c.Assert(err, IsNil) c.Assert(myList.Size(), Equals, uint(3)) err = myList.Add(hash3, "fileForHash3") c.Assert(err, IsNil) c.Assert(myList.Size(), Equals, uint(4)) // check (arbitrarily) second content line expected1 := base64.StdEncoding.EncodeToString(hash1) + " fileForHash1" actual1, err := myList.Get(1) c.Assert(err, IsNil) c.Assert(expected1, Equals, actual1) c.Assert(myList.IsHashed(), Equals, false) myList.SetDocHash() docHash := myList.GetDocHash() c.Assert(docHash, NotNil) c.Assert(myList.IsHashed(), Equals, true) ok := myList.Verify() c.Assert(ok, Equals, true) myDoc, err := myList.String() c.Assert(err, IsNil) // DEBUG fmt.Printf("MY_DOC - UNSIGNED:\n%s", myDoc) // END reader := strings.NewReader(myDoc) list2, err := ParseUnsignedBList(reader) c.Assert(err, IsNil) c.Assert(list2, NotNil) c.Assert(list2.Size(), Equals, uint(4)) c.Assert(list2.IsHashed(), Equals, true) c.Assert(list2.Verify(), Equals, true) str, err := list2.String() c.Assert(err, IsNil) c.Assert(str, Equals, myDoc) // yes, this is fully redundant docHash2 := list2.GetDocHash() c.Assert(bytes.Equal(docHash2, docHash), Equals, true) }