bpki.h(3)

📦
version 2.2.0 · 2 versions
, in fedora 44

okay so bestie, sit down, hydrate, grab a snack 🍓 — this is bpki.h(3) from the Library Functions Manual, and it is lowkey way more interesting than the title makes it sound. no cap. 💅

✨ NAME ✨

bpki.h — Механизмы СТБ 34.101.78 (bpki).

aka: this header is where the СТБ 34.101.78 mechanisms live. that's the whole vibe. 💜


🎀 SYNOPSIS 🎀

#include 'bee2/defs.h'

💖 ФУНКЦИИ 💖 — the functions, obvi

  • err_t bpkiPrivkeyWrap (octet epki[], size_t *epki_len, const octet privkey[], size_t privkey_len, const octet pwd[], size_t pwd_len, const octet salt[8], size_t iter) — creating a container with a private key inside 🫙✨
  • err_t bpkiPrivkeyUnwrap (octet privkey[], size_t *privkey_len, const octet epki[], size_t epki_len, const octet pwd[], size_t pwd_len) — parsing (taking apart) a container with a private key 🔓
  • err_t bpkiShareWrap (octet epki[], size_t *epki_len, const octet share[], size_t share_len, const octet pwd[], size_t pwd_len, const octet salt[8], size_t iter) — creating a container with a partial secret 🧩
  • err_t bpkiShareUnwrap (octet share[], size_t *share_len, const octet epki[], size_t epki_len, const octet pwd[], size_t pwd_len) — parsing a container with a partial secret 🔍
  • err_t bpkiCSRRewrap (octet csr[], size_t csr_len, const octet privkey[], size_t privkey_len) — re-issuing a certificate signing request 🔁
  • err_t bpkiCSRUnwrap (octet pubkey[], size_t *pubkey_len, const octet csr[], size_t csr_len) — parsing a certificate signing request 📜

🌈 ПОДРОБНОЕ ОПИСАНИЕ 🌈 — the full tea, no skimming

So what actually got implemented here? Some specific СТБ 34.101.78 (bpki) mechanisms:

  • managing containers with private keys from СТБ 34.101.45 (bign);
  • managing containers with partial secrets from СТБ 34.101.60 (bels).

Bonus round 🎁 — you can also drop private keys from the bign96 digital signature system (see bign.h) into a container, with the long-term parameters bign-curve192v1.

And another bonus: re-issuing of certificate requests got implemented too (Cerificate Signing Request, CSR). 🔁

The format of a container with a private key is described by the EncryptedPrivateKeyInfo type, which is defined in PKCS#8 (RFC 5208). Keeping that container safe is the PBKDF2 mechanism's job, and PBKDF2 is defined in PKCS#5 (RFC 8018). СТБ 34.101.78 is the one that pins down the exact format and the exact mechanism. 📜

PBKDF2's secret parameter is a password. And to raise the guarantees of protection, a full-fledged key can play the role of that password. That key gets split into partial secrets, which are also saved in EncryptedPrivateKeyInfo containers while being protected by ordinary passwords. 🧩

Splitting into partial secrets uses the standard bels parameters — standard public keys, in particular. The public key number (a number from 1 to 16) is encoded as an octet and tacked onto the front of the partial secret. That's exactly why the length of a partial secret in octets is one more than the standard length: 17 instead of 16, 25 instead of 24, and 33 instead of 32. 🔢

The certificate request format is defined in СТБ 34.101.17 (PKCS#10). A request contains the identification data of the certificate's future owner, their public key, technical extensions, and a signature over all of those fields made on the private key. The identification data, the public key, and some extensions get carried over into the certificate. The signature proves possession of the certificate's public key, i.e. knowledge of the corresponding private key. And re-issuing a request lets you prove possession on a new key pair while keeping the (bulky) identification data and extensions. 📝

💀 Ожидается ERR_BAD_INPUT 💀

(that's "ERR_BAD_INPUT is expected", for the non-Russian speakers in the chat)

All input pointers are valid. The exception is cases where a null pointer is passed as a request to determine the amount of memory that needs to be reserved on a repeated call (the [len?]ptr construct). 🙈


🎀 Функции (FUNCTIONS) 🎀

okay bestie, deep breath, this is the ✨function era✨ of the page. six of them. all err_t. all here. let's go 💅


🦋 bpkiCSRRewrap

err_t bpkiCSRRewrap (octet csr[], size_t csr_len, const octet privkey[],
    size_t privkey_len)

so the vibe here is a glow-up for a request: a brand-new public key gets built out of the private key [privkey_len]privkey, that new public key gets embedded into the certificate issuance request [csr_len]csr, and then the request gets signed on privkey. rewrap. iconic. ✨

  • Expected ERR_NOT_IMPLEMENTED — privkey_len == 32.
  • Expected ERR_BAD_FORMAT — the request format matches СТБ 34.101.17.
  • Expected ERR_BAD_FORMAT — the request uses the standard long-term parameters bign-curve256v1 and the algorithm bign-with-hbelt.

Returns

ERR_OK if the request was successfully re-issued, and an error code otherwise.

Arguments

  • csr [in/out] — the certificate issuance request
  • csr_len — the length of csr
  • privkey — the private key
  • privkey_len — the length of privkey

🧚 bpkiCSRUnwrap

err_t bpkiCSRUnwrap (octet pubkey[], size_t * pubkey_len, const octet csr[],
    size_t csr_len)

the reverse move, periodt: the signature of the certificate issuance request [csr_len]csr gets checked against the public key that's embedded right inside that request. if it checks out, the public key [pubkey_len?]pubkey gets extracted from the request. so satisfying 🫶

  • Expected ERR_BAD_FORMAT — the request format matches СТБ 34.101.17.
  • Expected ERR_BAD_FORMAT — the request uses the standard long-term parameters bign-curve256v1 and the algorithm bign-with-hbelt.

Returns

ERR_OK if the parsing went through, and an error code otherwise.

Arguments

  • pubkey — the public key
  • pubkey_len — the length of pubkey
  • csr — the certificate issuance request
  • csr_len — the length of csr

💜 bpkiPrivkeyUnwrap

err_t bpkiPrivkeyUnwrap (octet privkey[], size_t * privkey_len, const octet epki[],
    size_t epki_len, const octet pwd[], size_t pwd_len)

out of the container [epki_len]epki we pull the private key [privkey_len?]privkey, which has been protected using the PBKDF2 mechanism. the protection comes off with the password [pwd_len]pwd. 💖

Returns

ERR_OK if the private key was successfully extracted, and an error code otherwise.

Note. formally, to figure out the length privkey_len of the private key you have to strip the protection, and to do that you have to hand over the password. so the pwd pointer must be valid even when the privkey pointer is null, i.e. during the query of the privkey_len length. this does not take into account that the private key length can be determined indirectly from the container length. 😭

Arguments

  • privkey — the private key
  • privkey_len — the length of privkey
  • epki — the container with the private key
  • epki_len — the length of epki
  • pwd — the password
  • pwd_len — the length of pwd

🌸 bpkiPrivkeyWrap

err_t bpkiPrivkeyWrap (octet epki[], size_t * epki_len, const octet privkey[],
    size_t privkey_len, const octet pwd[], size_t pwd_len, const octet salt[8],
    size_t iter)

now we're making the container: [epki_len?]epki gets created holding the protected private key [privkey_len]privkey. the key is protected with the password [pwd_len]pwd. the protection mechanism is PBKDF2, with the synchronization seed ("salt") salt and the iteration count iter. chef's kiss 🔥

  • Expected ERR_BAD_PRIVKEY — privkey_len ∈ {32, 48, 64}.
  • Expected ERR_BAD_INPUT — iter >= 10000.

Returns

ERR_OK if the container was successfully created, and an error code otherwise.

Note. when epki is null, the privkey, pwd and salt pointers may be null. ✨

Arguments

  • epki — the container with the private key
  • epki_len — the length of epki
  • privkey — the private key
  • privkey_len — the length of privkey
  • pwd — the password
  • pwd_len — the length of pwd
  • salt — the PBKDF2 synchronization seed ("salt")
  • iter — the number of iterations in PBKDF2

👑 bpkiShareUnwrap

err_t bpkiShareUnwrap (octet share[], size_t * share_len, const octet epki[],
    size_t epki_len, const octet pwd[], size_t pwd_len)

out of the container [epki_len]epki we pull the partial secret [share_len?]share, which has been protected using the PBKDF2 mechanism. the protection comes off with the password [pwd_len]pwd. same energy, different secret 🦋

  • Expected ERR_BAD_SECKEY — if share != 0, then 1 <= share[0] <= 16.

Returns

ERR_OK if the partial secret was successfully extracted, and an error code otherwise.

Note. formally, to figure out the length share_len of the partial secret you have to strip the protection, and to do that you have to hand over the password. so the pwd pointer must be valid even when the share pointer is null, i.e. during the query of the share_len length. this does not take into account that the partial secret length can be determined indirectly from the container length. 💀

Arguments

  • share — the partial secret
  • share_len — the length of share
  • epki — the container with the partial secret
  • epki_len — the length of epki
  • pwd — the password
  • pwd_len — the length of pwd

🌈 bpkiShareWrap

err_t bpkiShareWrap (octet epki[], size_t * epki_len, const octet share[],
    size_t share_len, const octet pwd[], size_t pwd_len, const octet salt[8],
    size_t iter)

and the wrap for the partial secret: the container [epki_len?]epki gets created holding the protected partial secret [share_len]share. the key is protected with the password [pwd_len]pwd. the protection mechanism is PBKDF2, with the synchronization seed ("salt") salt and the iteration count iter. 💅

  • Expected ERR_BAD_SHAREKEY — share_len ∈ {17, 25, 33}.
  • Expected ERR_BAD_SHAREKEY — if share != 0, then 1 <= share[0] <= 16.
  • Expected ERR_BAD_INPUT — iter >= 10000.

Returns

ERR_OK if the container was successfully created, and an error code otherwise.

Note. in the prefix of the partial secret, the number of the corresponding public key is written (from the standard list of public keys). the public key is used when the key is assembled from the partial secrets. 🧠✨
Note. when epki is null, the share, pwd and salt pointers may be null.

Arguments

  • epki — the container with the partial secret
  • epki_len — the length of epki
  • share — the partial secret
  • share_len — the length of share
  • pwd — the password
  • pwd_len — the length of pwd
  • salt — the PBKDF2 synchronization seed ("salt")
  • iter — the number of iterations in PBKDF2

🌟 Автор (AUTHOR) 🌟

Automatically created by Doxygen for Библиотека Bee2 from the source text. 🤖💖


aaaand that's the whole page bestie, you ate it 💅 the whole thing ships from Библиотека Bee2, dated Вс 25 Янв 2026 00:00:00, and it lives at bpki.h(3). go forth and rewrap some requests 🫶🎀

📦 where this page comes from