123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- /*
- *******************************************************************************
- \file cmd_cvc.c
- \brief Command-line interface to Bee2: managing CV-certificates
- \project bee2/cmd
- \created 2022.08.20
- \version 2023.06.19
- \copyright The Bee2 authors
- \license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
- *******************************************************************************
- */
- #include "../cmd.h"
- #include <bee2/core/err.h>
- #include <bee2/core/blob.h>
- #include <bee2/core/hex.h>
- #include <bee2/core/mem.h>
- #include <bee2/core/str.h>
- #include <bee2/core/util.h>
- #include <stdio.h>
- /*
- *******************************************************************************
- Печать сертификата
- *******************************************************************************
- */
- err_t cmdCVCPrint(const btok_cvc_t* cvc, const char* scope)
- {
- err_t code = ERR_OK;
- // проверить содержимое
- code = btokCVCCheck(cvc);
- ERR_CALL_CHECK(code);
- // печать всех полей
- if (scope == 0)
- {
- printf("authority: %s\n", cvc->authority);
- printf("holder: %s\n", cvc->holder);
- printf("pubkey: ");
- code = cmdPrintMem2(cvc->pubkey, cvc->pubkey_len);
- ERR_CALL_CHECK(code);
- printf("\nhat_eid: ");
- code = cmdPrintMem(cvc->hat_eid, sizeof(cvc->hat_eid));
- ERR_CALL_CHECK(code);
- printf("\nhat_esign: ");
- code = cmdPrintMem(cvc->hat_esign, sizeof(cvc->hat_esign));
- ERR_CALL_CHECK(code);
- printf("\nfrom: ");
- code = cmdPrintDate(cvc->from);
- ERR_CALL_CHECK(code);
- printf("\nuntil: ");
- code = cmdPrintDate(cvc->until);
- ERR_CALL_CHECK(code);
- printf("\nsig: ");
- code = cmdPrintMem2(cvc->sig, cvc->sig_len);
- }
- // печать отдельных полей
- else if (strEq(scope, "authority"))
- printf("%s", cvc->authority);
- else if (strEq(scope, "holder"))
- printf("%s", cvc->holder);
- else if (strEq(scope, "from"))
- code = cmdPrintDate(cvc->from);
- else if (strEq(scope, "until"))
- code = cmdPrintDate(cvc->until);
- else if (strEq(scope, "eid"))
- code = cmdPrintMem(cvc->hat_eid, sizeof(cvc->hat_eid));
- else if (strEq(scope, "esign"))
- code = cmdPrintMem(cvc->hat_esign, sizeof(cvc->hat_esign));
- else if (strEq(scope, "pubkey"))
- code = cmdPrintMem(cvc->pubkey, cvc->pubkey_len);
- else if (strEq(scope, "sig"))
- code = cmdPrintMem(cvc->sig, cvc->sig_len);
- else
- code = ERR_CMD_PARAMS;
- // завершить
- ERR_CALL_CHECK(code);
- printf("\n");
- return code;
- }
- /*
- *******************************************************************************
- Управление коллекцией сертификатов
- *******************************************************************************
- */
- err_t cmdCVCsCreate(octet* certs, size_t* certs_len, const char* descr)
- {
- err_t code;
- int argc;
- char** argv;
- int pos;
- size_t len;
- // pre
- ASSERT(memIsValid(certs_len, O_PER_S));
- ASSERT(memIsNullOrValid(certs, *certs_len));
- ASSERT(strIsValid(descr));
- // создать список файлов сертификатов
- code = cmdArgCreate(&argc, &argv, descr);
- ERR_CALL_CHECK(code);
- // просмотреть список
- len = 0;
- for (pos = 0; pos < argc; ++pos)
- {
- size_t size;
- // определить размер файла
- size = cmdFileSize(argv[pos]);
- code = size != SIZE_MAX ? ERR_OK : ERR_FILE_READ;
- ERR_CALL_HANDLE(code, cmdArgClose(argv));
- // режим чтения?
- if (certs)
- {
- // выход за границы?
- code = len + size <= *certs_len ? ERR_OK : ERR_OUTOFMEMORY;
- ERR_CALL_HANDLE(code, cmdArgClose(argv));
- // читать сертификат
- code = cmdFileReadAll(certs + len, &size, argv[pos]);
- ERR_CALL_HANDLE(code, cmdArgClose(argv));
- }
- // увеличить длину коллекции
- len += size;
- }
- cmdArgClose(argv);
- // завершить
- *certs_len = len;
- return code;
- }
- err_t cmdCVCsCount(size_t* count, const octet* certs, size_t certs_len)
- {
- ASSERT(memIsValid(certs, certs_len));
- ASSERT(memIsValid(count, O_PER_S));
- // цикл по сертификатам
- for (*count = 0; certs_len; ++*count)
- {
- size_t len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- return ERR_BAD_CERTRING;
- certs += len, certs_len -= len;
- }
- return ERR_OK;
- }
- err_t cmdCVCsGet(size_t* offset, size_t* cert_len, const octet* certs,
- size_t certs_len, size_t num)
- {
- size_t pos;
- size_t len;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- ASSERT(memIsNullOrValid(offset, O_PER_S));
- ASSERT(memIsNullOrValid(cert_len, O_PER_S));
- // цикл по сертификатам
- for (pos = 0; certs_len; )
- {
- len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- return ERR_BAD_CERTRING;
- if (num-- == 0)
- {
- if (offset)
- *offset = pos;
- if (cert_len)
- *cert_len = len;
- return ERR_OK;
- }
- pos += len, certs += len, certs_len -= len;
- }
- return ERR_OUTOFRANGE;
- }
- err_t cmdCVCsGetLast(size_t* offset, size_t* cert_len, const octet* certs,
- size_t certs_len)
- {
- size_t pos;
- size_t len;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- ASSERT(memIsNullOrValid(offset, O_PER_S));
- ASSERT(memIsNullOrValid(cert_len, O_PER_S));
- // пустая коллекция?
- if (!certs_len)
- return ERR_OUTOFRANGE;
- // цикл по сертификатам
- for (pos = 0; certs_len; )
- {
- len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- return ERR_BAD_CERTRING;
- if (len == certs_len)
- break;
- pos += len, certs += len, certs_len -= len;
- }
- // сертификат найден
- if (offset)
- *offset = pos;
- if (cert_len)
- *cert_len = len;
- return ERR_OK;
- }
- err_t cmdCVCsFind(size_t* offset, const octet* certs, size_t certs_len,
- const octet* cert, size_t cert_len)
- {
- size_t pos;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- ASSERT(memIsValid(cert, cert_len));
- ASSERT(memIsNullOrValid(offset, O_PER_S));
- // цикл по сертификатам
- for (pos = 0; certs_len; )
- {
- size_t len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- return ERR_BAD_CERTRING;
- if (len == cert_len && memEq(certs, cert, cert_len))
- {
- if (offset)
- *offset = pos;
- return ERR_OK;
- }
- pos += len, certs += len, certs_len -= len;
- }
- return ERR_NOT_FOUND;
- }
- err_t cmdCVCsCheck(const octet* certs, size_t certs_len)
- {
- err_t code;
- void* stack;
- btok_cvc_t* cvc;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- // выделить и разметить память
- code = cmdBlobCreate(stack, sizeof(btok_cvc_t));
- ERR_CALL_CHECK(code);
- cvc = (btok_cvc_t*)stack;
- // цикл по сертификатам
- while (certs_len)
- {
- // разобрать сертификат
- size_t len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- code = ERR_BAD_CERTRING;
- else
- code = btokCVCUnwrap(cvc, certs, len, 0, 0);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- // к следующему
- certs += len, certs_len -= len;
- }
- // завершить
- cmdBlobClose(stack);
- return code;
- }
- err_t cmdCVCsVal(const octet* certs, size_t certs_len, const octet date[6])
- {
- err_t code;
- void* stack;
- size_t len;
- btok_cvc_t* cvca;
- btok_cvc_t* cvc;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- ASSERT(memIsNullOrValid(date, 6));
- // пустая цепочка?
- if (!certs_len)
- return ERR_OK;
- // выделить и разметить память
- code = cmdBlobCreate(stack, 2 * sizeof(btok_cvc_t));
- ERR_CALL_CHECK(code);
- cvca = (btok_cvc_t*)stack;
- cvc = cvca + 1;
- // найти и разобрать первый сертификат
- len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- code = ERR_BAD_CERT;
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- code = btokCVCUnwrap(cvca, certs, len, 0, 0);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- certs_len -= len, certs += len;
- // цикл по остальным сертификатам
- while (certs_len)
- {
- // разобрать сертификат
- len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- code = ERR_BAD_CERT;
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- // проверить сертификат
- if (len == certs_len && date && !memIsZero(date, 6))
- code = btokCVCVal2(cvc, certs, len, cvca, date);
- else
- code = btokCVCVal2(cvc, certs, len, cvca, 0);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- // к следующему сертификату
- certs_len -= len, certs += len;
- // издатель <- эмитент
- memCopy(cvca, cvc, sizeof(btok_cvc_t));
- }
- // завершить
- cmdBlobClose(stack);
- return code;
- }
- err_t cmdCVCsPrint(const octet* certs, size_t certs_len)
- {
- err_t code;
- void* stack;
- btok_cvc_t* cvc;
- // pre
- ASSERT(memIsValid(certs, certs_len));
- // выделить и разметить память
- code = cmdBlobCreate(stack, sizeof(btok_cvc_t));
- cvc = (btok_cvc_t*)stack;
- // цикл по сертификатам
- while (certs_len)
- {
- // разобрать сертификат
- size_t len = btokCVCLen(certs, certs_len);
- if (len == SIZE_MAX)
- code = ERR_BAD_CERTRING;
- else
- code = btokCVCUnwrap(cvc, certs, len, 0, 0);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- // печатать
- printf(" %s (%u bits, issued by %s, ",
- cvc->holder, (unsigned)cvc->pubkey_len * 2, cvc->authority);
- code = cmdPrintDate(cvc->from);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- printf("-");
- code = cmdPrintDate(cvc->until);
- ERR_CALL_HANDLE(code, cmdBlobClose(stack));
- printf(")\n");
- // к следующему
- certs += len, certs_len -= len;
- }
- // завершить
- cmdBlobClose(stack);
- return code;
- }
|