ssize_t available_cert_space(pesign_context *ctx) { cert_iter iter; int rc = cert_iter_init(&iter, ctx->outpe); if (rc < 0) return -1; data_directory *dd; rc = pe_getdatadir(ctx->outpe, &dd); if (rc < 0) return -1; ssize_t totalsize = dd->certs.size; ssize_t foundsize = 0; void *data; ssize_t datalen; while (1) { rc = next_cert(&iter, &data, &datalen); if (rc <= 0) break; foundsize += datalen; } return totalsize - foundsize; }
int list_signatures(pesign_context *ctx) { cert_iter iter; int rc = cert_iter_init(&iter, ctx->inpe); if (rc < 0) { printf("No certificate list found.\n"); return rc; } void *data; ssize_t datalen; int nsigs = 0; rc = 0; while (1) { rc = next_cert(&iter, &data, &datalen); if (rc <= 0) break; SEC_PKCS7DecoderContext *dc = NULL; saw_content = 0; dc = SEC_PKCS7DecoderStart(handle_bytes, NULL, NULL, NULL, NULL, NULL, decryption_allowed); if (dc == NULL) { fprintf(stderr, "SEC_PKCS7DecoderStart failed\n"); exit(1); } SECStatus status = SEC_PKCS7DecoderUpdate(dc, data, datalen); if (status != SECSuccess) { fprintf(stderr, "Found invalid certificate\n"); continue; } SEC_PKCS7ContentInfo *cinfo = SEC_PKCS7DecoderFinish(dc); if (cinfo == NULL) { fprintf(stderr, "Found invalid certificate\n"); continue; } nsigs++; printf("---------------------------------------------\n"); printf("Content was%s encrypted.\n", SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not"); if (SEC_PKCS7ContentIsSigned(cinfo)) { char *signer_cname, *signer_ename; SECItem *signing_time; if (saw_content) { printf("Signature is "); PORT_SetError(0); if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE)) { printf("valid.\n"); } else { printf("invalid (Reason: 0x%08x).\n", (uint32_t)PORT_GetError()); } } else { printf("Content is detached; signature cannot " "be verified.\n"); } signer_cname = SEC_PKCS7GetSignerCommonName(cinfo); if (signer_cname != NULL) { printf("The signer's common name is %s\n", signer_cname); PORT_Free(signer_cname); } else { printf("No signer common name.\n"); } signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo); if (signer_ename != NULL) { printf("The signer's email address is %s\n", signer_ename); PORT_Free(signer_ename); } else { printf("No signer email address.\n"); } signing_time = SEC_PKCS7GetSigningTime(cinfo); if (signing_time != NULL) { printf("Signing time: %s\n", DER_TimeChoiceDayToAscii(signing_time)); } else { printf("No signing time included.\n"); } printf("There were%s certs or crls included.\n", SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no"); SEC_PKCS7DestroyContentInfo(cinfo); } } if (nsigs) { printf("---------------------------------------------\n"); } else { printf("No signatures found.\n"); } return rc; }
int parse_signatures(pesign_context *ctx) { cert_iter iter; int rc = cert_iter_init(&iter, ctx->inpe); if (rc < 0) return -1; void *data; ssize_t datalen; int nsigs = 0; rc = 0; while (1) { rc = next_cert(&iter, &data, &datalen); if (rc <= 0) break; nsigs++; } if (nsigs == 0) { ctx->cms_ctx.num_signatures = 0; ctx->cms_ctx.signatures = NULL; return 0; } SECItem **signatures = calloc(nsigs, sizeof (SECItem *)); if (!signatures) return -1; rc = cert_iter_init(&iter, ctx->inpe); if (rc < 0) goto err; int i = 0; while (1) { rc = next_cert(&iter, &data, &datalen); if (rc <= 0) break; signatures[i] = calloc(1, sizeof (SECItem *)); if (!signatures[i]) goto err; signatures[i]->data = calloc(1, datalen); if (!signatures[i]->data) goto err; memcpy(signatures[i]->data, data, datalen); signatures[i]->len = datalen; signatures[i]->type = siBuffer; i++; } ctx->cms_ctx.num_signatures = nsigs; ctx->cms_ctx.signatures = signatures; return 0; err: if (signatures) { for (i = 0; i < nsigs; i++) { if (signatures[i]) { if (signatures[i]->data) free(signatures[i]->data); free(signatures[i]); } } free(signatures); } return -1; }