Код: Выделить всё
void signPDF(const char* pdfFilePath, const char* yubikeyPIN) {
// Open PDF file
HPDF_Doc pdf = HPDF_New(error_handler, NULL);
if (!pdf) {
fprintf(stderr, "Error: Cannot create PDF object\n");
return;
}
// Add a page to the document
HPDF_Page page = HPDF_AddPage(pdf);
// Set the font and size
HPDF_Font font = HPDF_GetFont(pdf, "Helvetica", NULL);
HPDF_Page_SetFontAndSize(page, font, 24);
// Write some text
HPDF_Page_BeginText(page);
HPDF_Page_TextOut(page, 50, 700, "Not so Random!");
HPDF_Page_EndText(page);
// Save PDF content to stream
if (HPDF_OK != HPDF_SaveToStream(pdf)) {
fprintf(stderr, "Error: Cannot save PDF to stream\n");
HPDF_Free(pdf);
return;
}
// Get the size of the stream
HPDF_UINT32 contentLen = HPDF_GetStreamSize(pdf);
// Allocate memory for the content
HPDF_BYTE *content = (HPDF_BYTE *)malloc(contentLen);
// Perform signing operation using YubiKey's PIV
ykpiv_state *state;
if (ykpiv_init(&state, 0) != YKPIV_OK) {
fprintf(stderr, "Error: Cannot initialize YubiKey PIV\n");
return;
}
ykpiv_rc res = ykpiv_connect(state, NULL);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: ykpiv_connect failed with code %d\n", res);
return;
}
int tries;
res = ykpiv_verify(state, yubikeyPIN, &tries);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: Cannot authenticate with YubiKey\n");
return;
}
size_t signatureLen = YKPIV_MAX_SIGNATURE_SIZE;
unsigned char signature[YKPIV_MAX_SIGNATURE_SIZE];
res =
ykpiv_sign_data(state, content, contentLen, signature, &signatureLen,
YKPIV_ALGO_ECCP256, YKPIV_KEY_SIGNATURE);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: Cannot sign PDF content. Error code: %d\n", res);
ykpiv_done(state);
HPDF_Free(pdf);
return;
}
// Save the signed PDF file
if (HPDF_SaveToFile(pdf, "signed_example.pdf") != HPDF_OK) {
fprintf(stderr, "Error: Cannot save signed PDF file.\n");
return;
}
printf("PDF file signed successfully.\n");
}void signPDF(const char* pdfFilePath, const char* yubikeyPIN) {
// Open PDF file
HPDF_Doc pdf = HPDF_New(error_handler, NULL);
if (!pdf) {
fprintf(stderr, "Error: Cannot create PDF object\n");
return;
}
// Add a page to the document
HPDF_Page page = HPDF_AddPage(pdf);
// Set the font and size
HPDF_Font font = HPDF_GetFont(pdf, "Helvetica", NULL);
HPDF_Page_SetFontAndSize(page, font, 24);
// Write some text
HPDF_Page_BeginText(page);
HPDF_Page_TextOut(page, 50, 700, "Not so Random!");
HPDF_Page_EndText(page);
// Save PDF content to stream
if (HPDF_OK != HPDF_SaveToStream(pdf)) {
fprintf(stderr, "Error: Cannot save PDF to stream\n");
HPDF_Free(pdf);
return;
}
// Get the size of the stream
HPDF_UINT32 contentLen = HPDF_GetStreamSize(pdf);
// Allocate memory for the content
HPDF_BYTE *content = (HPDF_BYTE *)malloc(contentLen);
// Perform signing operation using YubiKey's PIV
ykpiv_state *state;
if (ykpiv_init(&state, 0) != YKPIV_OK) {
fprintf(stderr, "Error: Cannot initialize YubiKey PIV\n");
return;
}
ykpiv_rc res = ykpiv_connect(state, NULL);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: ykpiv_connect failed with code %d\n", res);
return;
}
int tries;
res = ykpiv_verify(state, yubikeyPIN, &tries);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: Cannot authenticate with YubiKey\n");
return;
}
size_t signatureLen = YKPIV_MAX_SIGNATURE_SIZE;
unsigned char signature[YKPIV_MAX_SIGNATURE_SIZE];
res =
ykpiv_sign_data(state, content, contentLen, signature, &signatureLen,
YKPIV_ALGO_ECCP256, YKPIV_KEY_SIGNATURE);
if (res != YKPIV_OK) {
fprintf(stderr, "Error: Cannot sign PDF content. Error code: %d\n", res);
ykpiv_done(state);
HPDF_Free(pdf);
return;
}
// Save the signed PDF file
if (HPDF_SaveToFile(pdf, "signed_example.pdf") != HPDF_OK) {
fprintf(stderr, "Error: Cannot save signed PDF file.\n");
return;
}
printf("PDF file signed successfully.\n");
}
Я пробовал использовать библиотеку PoDoFo, но, похоже, это необходимо работайте только с заранее доступным закрытым ключом, что сводит на нет всю цель, поскольку ключ в любом случае не следует вынимать из YubiKey. Я пытался разобраться в том, как подписываются PDF-файлы, но создание функциональности с нуля для этого конкретного случая использования кажется слишком сложным.
Что мне можно попробовать дальше? Язык не является проблемой, если решение можно реализовать.
Подробнее здесь: https://stackoverflow.com/questions/783 ... mmatically