// 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 }
func ParseSiteList(in io.Reader) (stl *SiteList, err error) { var ( digSig, line []byte ) bin := bufio.NewReader(in) sl, err := xb.ParseSignedBList(bin) if err == nil { stl = &SiteList{SignedBList: *sl} err = stl.ReadContents(bin) if err == nil { // try to read the digital signature line line, err = xc.NextLineWithoutCRLF(bin) if err == nil || err == io.EOF { digSig, err = base64.StdEncoding.DecodeString(string(line)) } if err == nil || err == io.EOF { stl.SetDigSig(digSig) } } } if err == io.EOF { err = nil } return }
/** * Read a series of content lines, each consisting of a hash * followed by a space followed by a file name. The hash is * base-64 encoded. * * The text of the line, excluding the line terminator, is * included in the digest. */ func ReadContents(in *bufio.Reader, bList xc.BuildListI, isSigned bool) ( err error) { // XXX NONSENSE var bl xc.BuildListI if isSigned { bl = bList.(*SignedBList) } else { bl = bList.(*UnsignedBList) } // END NONSENSE content := bl.GetContent() for err == nil { var ( hash, line []byte path string item *Item ) line, err = xc.NextLineWithoutCRLF(in) if err == nil || err == io.EOF { if bytes.Equal(line, xc.CONTENT_END) { break } else { // Parse the line. We expect it to consist of a base64- // encoded hash followed by a space followed by a POSIX // path. line = bytes.Trim(line, " \t") if len(line) == 0 { err = EmptyContentLine } else { parts := bytes.Split(line, SPACE_SEP) if len(parts) != 2 { err = IllFormedContentLine } else { var count int e := base64.StdEncoding maxLen := e.DecodedLen(len(parts[0])) hash = make([]byte, maxLen) count, err = e.Decode(hash, parts[0]) if err == nil { path = string(parts[1]) } hash = hash[:count] } } if err == nil { item, err = NewItem(hash, path) if err == nil { *content = append(*content, item) } } } } } return }
/** * Read a series of content lines, each consisting of a simple * name. This is an Internet domain name and so may contain no * spaces or other delimiters. The name must end with the * file separator (File.separator). * * The text of the line, excluding the line terminator, is * included in the digest. */ func (stl *SiteList) ReadContents(in *bufio.Reader) (err error) { for err == nil { var line []byte line, err = xc.NextLineWithoutCRLF(in) if err == nil || err == io.EOF { if bytes.Equal(line, xc.CONTENT_END) { break } else { stl.content = append(stl.content, string(line)) } } } 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 }