(fileContent: Buffer)
| 243 | * Extracts the signature block from a signed MCPB file |
| 244 | */ |
| 245 | export function extractSignatureBlock(fileContent: Buffer): { |
| 246 | originalContent: Buffer; |
| 247 | pkcs7Signature?: Buffer; |
| 248 | } { |
| 249 | // Look for signature footer at the end |
| 250 | const footerBytes = Buffer.from(SIGNATURE_FOOTER, "utf-8"); |
| 251 | const footerIndex = fileContent.lastIndexOf(footerBytes); |
| 252 | |
| 253 | if (footerIndex === -1) { |
| 254 | return { originalContent: fileContent }; |
| 255 | } |
| 256 | |
| 257 | // Look for signature header before footer |
| 258 | const headerBytes = Buffer.from(SIGNATURE_HEADER, "utf-8"); |
| 259 | let headerIndex = -1; |
| 260 | |
| 261 | // Search backwards from footer |
| 262 | for (let i = footerIndex - 1; i >= 0; i--) { |
| 263 | if (fileContent.slice(i, i + headerBytes.length).equals(headerBytes)) { |
| 264 | headerIndex = i; |
| 265 | break; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | if (headerIndex === -1) { |
| 270 | return { originalContent: fileContent }; |
| 271 | } |
| 272 | |
| 273 | // Extract original content (everything before signature block) |
| 274 | const originalContent = fileContent.slice(0, headerIndex); |
| 275 | |
| 276 | // Parse signature block |
| 277 | let offset = headerIndex + headerBytes.length; |
| 278 | |
| 279 | try { |
| 280 | // Read PKCS#7 signature length |
| 281 | const sigLength = fileContent.readUInt32LE(offset); |
| 282 | offset += 4; |
| 283 | |
| 284 | // Read PKCS#7 signature |
| 285 | const pkcs7Signature = fileContent.slice(offset, offset + sigLength); |
| 286 | |
| 287 | return { |
| 288 | originalContent, |
| 289 | pkcs7Signature, |
| 290 | }; |
| 291 | } catch { |
| 292 | return { originalContent: fileContent }; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | /** |
| 297 | * Verifies certificate chain against OS trust store |
no outgoing calls
no test coverage detected
searching dependent graphs…