Sign generates an ad-hoc code signature and writes it to out. out must have length at least Size(codeSize, id). data is the file content without the signature, of size codeSize. textOff and textSize is the file offset and size of the text segment. isMain is true if this is a main executable. id is t
(out []byte, data io.Reader, id string, codeSize, textOff, textSize int64, isMain bool)
| 206 | // id is the identifier used for signing (a field in CodeDirectory blob, which |
| 207 | // has no significance in ad-hoc signing). |
| 208 | func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int64, isMain bool) { |
| 209 | nhashes := (codeSize + pageSize - 1) / pageSize |
| 210 | idOff := int64(codeDirectorySize) |
| 211 | hashOff := idOff + int64(len(id)+1) |
| 212 | sz := Size(codeSize, id) |
| 213 | |
| 214 | // emit blob headers |
| 215 | sb := SuperBlob{ |
| 216 | magic: CSMAGIC_EMBEDDED_SIGNATURE, |
| 217 | length: uint32(sz), |
| 218 | count: 1, |
| 219 | } |
| 220 | blob := Blob{ |
| 221 | typ: CSSLOT_CODEDIRECTORY, |
| 222 | offset: superBlobSize + blobSize, |
| 223 | } |
| 224 | cdir := CodeDirectory{ |
| 225 | magic: CSMAGIC_CODEDIRECTORY, |
| 226 | length: uint32(sz) - (superBlobSize + blobSize), |
| 227 | version: 0x20400, |
| 228 | flags: 0x20002, // adhoc | linkerSigned |
| 229 | hashOffset: uint32(hashOff), |
| 230 | identOffset: uint32(idOff), |
| 231 | nCodeSlots: uint32(nhashes), |
| 232 | codeLimit: uint32(codeSize), |
| 233 | hashSize: sha256.Size, |
| 234 | hashType: CS_HASHTYPE_SHA256, |
| 235 | pageSize: uint8(pageSizeBits), |
| 236 | execSegBase: uint64(textOff), |
| 237 | execSegLimit: uint64(textSize), |
| 238 | } |
| 239 | if isMain { |
| 240 | cdir.execSegFlags = CS_EXECSEG_MAIN_BINARY |
| 241 | } |
| 242 | |
| 243 | outp := out |
| 244 | outp = sb.put(outp) |
| 245 | outp = blob.put(outp) |
| 246 | outp = cdir.put(outp) |
| 247 | |
| 248 | // emit the identifier |
| 249 | outp = puts(outp, []byte(id+"\000")) |
| 250 | |
| 251 | // emit hashes |
| 252 | var buf [pageSize]byte |
| 253 | h := sha256.New() |
| 254 | p := 0 |
| 255 | for p < int(codeSize) { |
| 256 | n, err := io.ReadFull(data, buf[:]) |
| 257 | if err == io.EOF { |
| 258 | break |
| 259 | } |
| 260 | if err != nil && err != io.ErrUnexpectedEOF { |
| 261 | panic(err) |
| 262 | } |
| 263 | if p+n > int(codeSize) { |
| 264 | n = int(codeSize) - p |
| 265 | } |