D2I_DSAPUBLICKEY(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’… D2I_DSAPUBLICKEY β€” decode & encode DSA keys (section 3, libcrypto bestie)

okay so real talk: this page is the entire DSA key glow-up station πŸ’– it's a whole family of d2i_* and i2d_* functions β€” d2i = DER β†’ internal object (decoding, "d2i" literally reads as DER-to-internal, iconic), i2d = internal β†’ DER (encoding). And yes, they're all formally listed under the name d2i_DSAPublicKey, i2d_DSAPublicKey, d2i_DSA_PUBKEY, i2d_DSA_PUBKEY, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY_fp, d2i_DSAPrivateKey, i2d_DSAPrivateKey, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey_fp, d2i_DSAparams, i2d_DSAparams, d2i_DSAparams_bio, i2d_DSAparams_bio, d2i_DSAparams_fp, i2d_DSAparams_fp, DSAparams_dup, d2i_DSA_SIG, i2d_DSA_SIG β€” decode and encode DSA keys`. That's the NAME section, we ate it, no crumbs. πŸ“


✨ SYNOPSIS ✨

bestie this is a LOT of signatures so buckle up, library is β€œlibcrypto” πŸŽ€

#include <openssl/dsa.h>

DSA *
d2i_DSAPublicKey(DSA **val_out, const unsigned char **der_in,
    long length);

int
i2d_DSAPublicKey(const DSA *val_in, unsigned char **der_out);
#include <openssl/x509.h>

DSA *
d2i_DSA_PUBKEY(DSA **val_out, const unsigned char **der_in,
    long length);

int
i2d_DSA_PUBKEY(const DSA *val_in, unsigned char **der_out);

DSA *
d2i_DSA_PUBKEY_bio(BIO *in_bio, DSA **val_out);

DSA *
d2i_DSA_PUBKEY_fp(FILE *in_fp, DSA **val_out);

int
i2d_DSA_PUBKEY_bio(BIO *out_bio, DSA *val_in);

int
i2d_DSA_PUBKEY_fp(FILE *out_fp, DSA *val_in);
#include <openssl/dsa.h>

DSA *
d2i_DSAPrivateKey(DSA **val_out, const unsigned char **der_in,
    long length);

int
i2d_DSAPrivateKey(const DSA *val_in, unsigned char **der_out);
#include <openssl/x509.h>

DSA *
d2i_DSAPrivateKey_bio(BIO *in_bio, DSA **val_out);

DSA *
d2i_DSAPrivateKey_fp(FILE *in_fp, DSA **val_out);

int
i2d_DSAPrivateKey_bio(BIO *out_bio, DSA *val_in);

int
i2d_DSAPrivateKey_fp(FILE *out_fp, DSA *val_in);
#include <openssl/dsa.h>

DSA *
d2i_DSAparams(DSA **val_out, const unsigned char **der_in, long length);

int
i2d_DSAparams(const DSA *val_in, unsigned char **der_out);

DSA *
d2i_DSAparams_bio(BIO *in_bio, DSA **val_out);

int
i2d_DSAparams_bio(BIO *out_bio, DSA *val_in);

DSA *
d2i_DSAparams_fp(FILE *in_fp, DSA **val_out);

int
i2d_DSAparams_fp(FILE, *out_fp, DSA *val_in);

DSA *
DSAparams_dup(DSA *val_in);

DSA_SIG *
d2i_DSA_SIG(DSA_SIG **val_out, const unsigned char **der_in,
    long length);

int
i2d_DSA_SIG(const DSA_SIG *val_in, unsigned char **der_out);

(and before anyone comes for me: yes, that last params one really is written i2d_DSAparams_fp(FILE, *out_fp, DSA *val_in); in the page β€” I'm not touching it, it's canon, iykyk πŸ’€)


🌸 DESCRIPTION 🌸

so the TL;DR is these functions decode and encode DSA keys and parameters. That's the whole vibe. For the details about the semantics, examples, caveats, and bugs, go read ASN1_item_d2i(3) β€” that's the parent manual, the main character, we're just the spin-off. πŸ‘‘

πŸ¦‹ the public key situation

d2i_DSAPublicKey() and i2d_DSAPublicKey() decode and encode the DSA public key components using a non-standard format, so consider using d2i_DSA_PUBKEY() and i2d_DSA_PUBKEY() instead. like, please. spare yourself. πŸ™ˆ

The actual data encoded depends on the value of val_in->write_params:

  • if val_in->write_params is zero, only the val_in->pub_key field is encoded as an ASN.1 INTEGER (minimalist, lowkey)
  • if val_in->write_params is 1, then a SEQUENCE consisting of the val_in->p, val_in->q, val_in->g, and val_in->pub_key fields is encoded (full send)

πŸ’– the standard public key ones

d2i_DSA_PUBKEY() and i2d_DSA_PUBKEY() decode and encode a DSA public key using an ASN.1 SubjectPublicKeyInfo structure defined in RFC 5280 section 4.1 and documented in X509_PUBKEY_new(3).

d2i_DSA_PUBKEY_bio(), d2i_DSA_PUBKEY_fp(), i2d_DSA_PUBKEY_bio(), and i2d_DSA_PUBKEY_fp() are similar except that they decode or encode using a BIO or FILE pointer. same energy, different I/O flav πŸ’…

πŸ”₯ private keys (handle with care)

d2i_DSAPrivateKey() and i2d_DSAPrivateKey() decode and encode the DSA private key components. The DSA object passed to the private key encoding functions should have all the private key components present.

These functions use a non-standard structure consisting of a SEQUENCE containing the val_in->p, val_in->q, val_in->g, val_in->pub_key, and val_in->priv_key fields.

⚠️ ok serious moment: this data format is unencrypted. For private key security when writing private keys to files, consider using PEM_write_DSAPrivateKey(3) instead. fr fr, do not just dump your private key raw, that's giving "posted my password in the group chat" πŸ˜­πŸ”

d2i_DSAPrivateKey_bio(), d2i_DSAPrivateKey_fp(), i2d_DSAPrivateKey_bio(), and i2d_DSAPrivateKey_fp() are similar except that they decode or encode using a BIO or FILE pointer.

🧚 parameters, bestie

d2i_DSAparams() and i2d_DSAparams() decode and encode the DSA parameters using an ASN.1 Dss-Parms structure defined in RFC 3279 section 2.3.2 and used for the parameters field of the ASN.1 AlgorithmIdentifier structure defined in RFC 5280 section 4.1.1.2.

d2i_DSAparams_bio(), i2d_DSAparams_bio(), d2i_DSAparams_fp(), i2d_DSAparams_fp() are similar except that they decode or encode using a BIO or FILE pointer.

DSAparams_dup() allocates and initializes an empty DSA object and copies the DSA parameters from val_in to it by calling i2d_DSAparams() and d2i_DSAparams(). And heads up β€” if a private or public key are present in val_in, they are not copied. parameters only, we're keeping it cute and narrow πŸ’«

πŸŽ€ signatures

d2i_DSA_SIG() and i2d_DSA_SIG() decode and encode a DSA signature using an ASN.1 Dss-Sig-Value structure as defined in RFC 3279 section 2.2.2 and used for the signatureValue field of the ASN.1 Certificate structure described in RFC 5280 sections 4.1.1.3 and 5.1.1.3.


⭐ RETURN VALUES ⭐

the decoding/dup gang β€” d2i_DSAPublicKey(), d2i_DSA_PUBKEY(), d2i_DSA_PUBKEY_bio(), d2i_DSA_PUBKEY_fp(), d2i_DSAPrivateKey(), d2i_DSAPrivateKey_bio(), d2i_DSAPrivateKey_fp(), d2i_DSAparams(), d2i_DSAparams_bio(), d2i_DSAparams_fp(), and DSAparams_dup() β€” return a valid DSA object, or NULL if an error occurs. 😭 when it's NULL it's not slaying.

d2i_DSA_SIG() returns a valid DSA_SIG object, or NULL if an error occurs.


🌈 SEE ALSO 🌈

go read these next, they're all linked and they all matter:


πŸ‘‘ STANDARDS πŸ‘‘

RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, section 4.1: Basic Certificate Fields

RFC 3279: Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile:

  • section 2.2.2: DSA Signature Algorithm
  • section 2.3.2: DSA Signature Keys

🫢 HISTORY 🫢

the lore drop, chronological, no skips:

d2i_DSAPublicKey(), i2d_DSAPublicKey(), d2i_DSAPrivateKey(), and i2d_DSAPrivateKey() first appeared in SSLeay 0.6.0.

d2i_DSAPrivateKey_bio(), d2i_DSAPrivateKey_fp(), i2d_DSAPrivateKey_bio(), i2d_DSAPrivateKey_fp(), d2i_DSAparams(), i2d_DSAparams(), d2i_DSAparams_bio(), i2d_DSAparams_bio(), d2i_DSAparams_fp(), i2d_DSAparams_fp(), and DSAparams_dup() first appeared in SSLeay 0.8.0. These functions have been available since OpenBSD 2.4.

d2i_DSA_SIG() and i2d_DSA_SIG() first appeared in OpenSSL 0.9.3 and have been available since OpenBSD 2.6.

d2i_DSA_PUBKEY(), i2d_DSA_PUBKEY(), d2i_DSA_PUBKEY_bio(), d2i_DSA_PUBKEY_fp(), i2d_DSA_PUBKEY_bio(), and i2d_DSA_PUBKEY_fp() first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7.


okay that's the whole page, you're officially DSA-literate, I'm so proud πŸ₯ΉπŸ’œ this cutie came from Debian, dated June 8, 2025, and it lives at D2I_DSAPUBLICKEY(3). mwah, go encode something responsibly πŸ’…βœ¨

πŸ“¦ where this page comes from