197403Sobrien/*-
297403Sobrien * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
397403Sobrien *
497403Sobrien * Licensed under the Apache License 2.0 (the "License").  You may not use
597403Sobrien * this file except in compliance with the License.  You can obtain a copy
697403Sobrien * in the file LICENSE in the source distribution or at
797403Sobrien * https://www.openssl.org/source/license.html
897403Sobrien */
997403Sobrien
1097403Sobrien#include <openssl/pem.h>
1197403Sobrien#include <openssl/core_names.h>
1297403Sobrien
1397403Sobrien/* Raw DSA params for P, Q and G */
1497403Sobrienstatic const unsigned char dsa_p[] = {
1597403Sobrien    0xa2, 0x9b, 0x88, 0x72, 0xce, 0x8b, 0x84, 0x23,
1697403Sobrien    0xb7, 0xd5, 0xd2, 0x1d, 0x4b, 0x02, 0xf5, 0x7e,
1797403Sobrien    0x03, 0xe9, 0xe6, 0xb8, 0xa2, 0x58, 0xdc, 0x16,
18169691Skan    0x61, 0x1b, 0xa0, 0x98, 0xab, 0x54, 0x34, 0x15,
1997403Sobrien    0xe4, 0x15, 0xf1, 0x56, 0x99, 0x7a, 0x3e, 0xe2,
2097403Sobrien    0x36, 0x65, 0x8f, 0xa0, 0x93, 0x26, 0x0d, 0xe3,
2197403Sobrien    0xad, 0x42, 0x2e, 0x05, 0xe0, 0x46, 0xf9, 0xec,
2297403Sobrien    0x29, 0x16, 0x1a, 0x37, 0x5f, 0x0e, 0xb4, 0xef,
2397403Sobrien    0xfc, 0xef, 0x58, 0x28, 0x5c, 0x5d, 0x39, 0xed,
2497403Sobrien    0x42, 0x5d, 0x7a, 0x62, 0xca, 0x12, 0x89, 0x6c,
2597403Sobrien    0x4a, 0x92, 0xcb, 0x19, 0x46, 0xf2, 0x95, 0x2a,
2697403Sobrien    0x48, 0x13, 0x3f, 0x07, 0xda, 0x36, 0x4d, 0x1b,
2797403Sobrien    0xdf, 0x6b, 0x0f, 0x71, 0x39, 0x98, 0x3e, 0x69,
2897403Sobrien    0x3c, 0x80, 0x05, 0x9b, 0x0e, 0xac, 0xd1, 0x47,
2997403Sobrien    0x9b, 0xa9, 0xf2, 0x85, 0x77, 0x54, 0xed, 0xe7,
3097403Sobrien    0x5f, 0x11, 0x2b, 0x07, 0xeb, 0xbf, 0x35, 0x34,
3197403Sobrien    0x8b, 0xbf, 0x3e, 0x01, 0xe0, 0x2f, 0x2d, 0x47,
3297403Sobrien    0x3d, 0xe3, 0x94, 0x53, 0xf9, 0x9d, 0xd2, 0x36,
3397403Sobrien    0x75, 0x41, 0xca, 0xca, 0x3b, 0xa0, 0x11, 0x66,
3497403Sobrien    0x34, 0x3d, 0x7b, 0x5b, 0x58, 0xa3, 0x7b, 0xd1,
3597403Sobrien    0xb7, 0x52, 0x1d, 0xb2, 0xf1, 0x3b, 0x86, 0x70,
3697403Sobrien    0x71, 0x32, 0xfe, 0x09, 0xf4, 0xcd, 0x09, 0xdc,
3797403Sobrien    0x16, 0x18, 0xfa, 0x34, 0x01, 0xeb, 0xf9, 0xcc,
3897403Sobrien    0x7b, 0x19, 0xfa, 0x94, 0xaa, 0x47, 0x20, 0x88,
3997403Sobrien    0x13, 0x3d, 0x6c, 0xb2, 0xd3, 0x5c, 0x11, 0x79,
4097403Sobrien    0xc8, 0xc8, 0xff, 0x36, 0x87, 0x58, 0xd5, 0x07,
4197403Sobrien    0xd9, 0xf9, 0xa1, 0x7d, 0x46, 0xc1, 0x10, 0xfe,
4297403Sobrien    0x31, 0x44, 0xce, 0x9b, 0x02, 0x2b, 0x42, 0xe4,
4397403Sobrien    0x19, 0xeb, 0x4f, 0x53, 0x88, 0x61, 0x3b, 0xfc,
4497403Sobrien    0x3e, 0x26, 0x24, 0x1a, 0x43, 0x2e, 0x87, 0x06,
4597403Sobrien    0xbc, 0x58, 0xef, 0x76, 0x11, 0x72, 0x78, 0xde,
4697403Sobrien    0xab, 0x6c, 0xf6, 0x92, 0x61, 0x82, 0x91, 0xb7
4797403Sobrien};
4897403Sobrien
4997403Sobrienstatic const unsigned char dsa_q[] = {
5097403Sobrien    0xa3, 0xbf, 0xd9, 0xab, 0x78, 0x84, 0x79, 0x4e,
5197403Sobrien    0x38, 0x34, 0x50, 0xd5, 0x89, 0x1d, 0xc1, 0x8b,
5297403Sobrien    0x65, 0x15, 0x7b, 0xdc, 0xfc, 0xda, 0xc5, 0x15,
5397403Sobrien    0x18, 0x90, 0x28, 0x67
5497403Sobrien};
5597403Sobrien
56132720Skanstatic const unsigned char dsa_g[] = {
57132720Skan    0x68, 0x19, 0x27, 0x88, 0x69, 0xc7, 0xfd, 0x3d,
5897403Sobrien    0x2d, 0x7b, 0x77, 0xf7, 0x7e, 0x81, 0x50, 0xd9,
5997403Sobrien    0xad, 0x43, 0x3b, 0xea, 0x3b, 0xa8, 0x5e, 0xfc,
6097403Sobrien    0x80, 0x41, 0x5a, 0xa3, 0x54, 0x5f, 0x78, 0xf7,
6197403Sobrien    0x22, 0x96, 0xf0, 0x6c, 0xb1, 0x9c, 0xed, 0xa0,
6297403Sobrien    0x6c, 0x94, 0xb0, 0x55, 0x1c, 0xfe, 0x6e, 0x6f,
6397403Sobrien    0x86, 0x3e, 0x31, 0xd1, 0xde, 0x6e, 0xed, 0x7d,
6497403Sobrien    0xab, 0x8b, 0x0c, 0x9d, 0xf2, 0x31, 0xe0, 0x84,
65132720Skan    0x34, 0xd1, 0x18, 0x4f, 0x91, 0xd0, 0x33, 0x69,
66    0x6b, 0xb3, 0x82, 0xf8, 0x45, 0x5e, 0x98, 0x88,
67    0xf5, 0xd3, 0x1d, 0x47, 0x84, 0xec, 0x40, 0x12,
68    0x02, 0x46, 0xf4, 0xbe, 0xa6, 0x17, 0x94, 0xbb,
69    0xa5, 0x86, 0x6f, 0x09, 0x74, 0x64, 0x63, 0xbd,
70    0xf8, 0xe9, 0xe1, 0x08, 0xcd, 0x95, 0x29, 0xc3,
71    0xd0, 0xf6, 0xdf, 0x80, 0x31, 0x6e, 0x2e, 0x70,
72    0xaa, 0xeb, 0x1b, 0x26, 0xcd, 0xb8, 0xad, 0x97,
73    0xbc, 0x3d, 0x28, 0x7e, 0x0b, 0x8d, 0x61, 0x6c,
74    0x42, 0xe6, 0x5b, 0x87, 0xdb, 0x20, 0xde, 0xb7,
75    0x00, 0x5b, 0xc4, 0x16, 0x74, 0x7a, 0x64, 0x70,
76    0x14, 0x7a, 0x68, 0xa7, 0x82, 0x03, 0x88, 0xeb,
77    0xf4, 0x4d, 0x52, 0xe0, 0x62, 0x8a, 0xf9, 0xcf,
78    0x1b, 0x71, 0x66, 0xd0, 0x34, 0x65, 0xf3, 0x5a,
79    0xcc, 0x31, 0xb6, 0x11, 0x0c, 0x43, 0xda, 0xbc,
80    0x7c, 0x5d, 0x59, 0x1e, 0x67, 0x1e, 0xaf, 0x7c,
81    0x25, 0x2c, 0x1c, 0x14, 0x53, 0x36, 0xa1, 0xa4,
82    0xdd, 0xf1, 0x32, 0x44, 0xd5, 0x5e, 0x83, 0x56,
83    0x80, 0xca, 0xb2, 0x53, 0x3b, 0x82, 0xdf, 0x2e,
84    0xfe, 0x55, 0xec, 0x18, 0xc1, 0xe6, 0xcd, 0x00,
85    0x7b, 0xb0, 0x89, 0x75, 0x8b, 0xb1, 0x7c, 0x2c,
86    0xbe, 0x14, 0x44, 0x1b, 0xd0, 0x93, 0xae, 0x66,
87    0xe5, 0x97, 0x6d, 0x53, 0x73, 0x3f, 0x4f, 0xa3,
88    0x26, 0x97, 0x01, 0xd3, 0x1d, 0x23, 0xd4, 0x67
89};
90
91/* Helper function to retrieve and print a key BIGNUM field */
92static void print_bn(BIO *bio, const EVP_PKEY *pkey, const char *name)
93{
94    BIGNUM *bn = NULL;
95
96    if (EVP_PKEY_get_bn_param(pkey, name, &bn) == 0)
97        return;
98
99    BIO_printf(bio, "  %s = 0x", name);
100    BN_print(bio, bn);
101    BIO_printf(bio, "\n");
102    BN_clear_free(bn);
103}
104
105/*
106 * Print DSA key info
107 *
108 * This method shows how to extract DSA data from an EVP_PKEY.
109 * There are simpler ways to print using EVP_PKEY_print_XXXX().
110 */
111static int dsa_print_key(const EVP_PKEY *pkey, int keypair,
112                         OSSL_LIB_CTX *libctx, const char *propq)
113{
114
115    int rv = 0, gindex, counter;
116    BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE);
117    unsigned char seed[2048];
118    size_t seedlen;
119
120    if (bio == NULL)
121        return 0;
122
123    /* Output hexadecimal representations of the BIGNUM objects. */
124    BIO_printf(bio, "\nPublic values:\n");
125    print_bn(bio, pkey, OSSL_PKEY_PARAM_FFC_P);
126    print_bn(bio, pkey, OSSL_PKEY_PARAM_FFC_Q);
127    print_bn(bio, pkey, OSSL_PKEY_PARAM_FFC_G);
128
129    if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_FFC_SEED, seed,
130                                        sizeof(seed), &seedlen) > 0) {
131        BIO_printf(bio, "  %s\n", OSSL_PKEY_PARAM_FFC_SEED);
132        BIO_dump(bio, seed, seedlen);
133    }
134    if (EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_FFC_GINDEX, &gindex) > 0) {
135        if (gindex != -1)
136            BIO_printf(bio, "  %s = %d\n", OSSL_PKEY_PARAM_FFC_GINDEX, gindex);
137    }
138    if (EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_FFC_PCOUNTER, &counter) > 0) {
139        if (counter != -1)
140            BIO_printf(bio, "  %s = %d\n", OSSL_PKEY_PARAM_FFC_PCOUNTER, counter);
141    }
142
143    if (keypair) {
144        fprintf(stdout, "\nPrivate value:\n");
145        print_bn(bio, pkey, OSSL_PKEY_PARAM_PRIV_KEY);
146
147        /* Output a PEM encoding of the public key. */
148        if (PEM_write_bio_PUBKEY_ex(bio, pkey, libctx, propq) == 0) {
149            fprintf(stderr, "Failed to output PEM-encoded public key\n");
150            goto cleanup;
151        }
152
153        /*
154         * Output a PEM encoding of the private key. Please note that this output is
155         * not encrypted. You may wish to use the arguments to specify encryption of
156         * the key if you are storing it on disk. See PEM_write_bio_PrivateKey_ex(3).
157         */
158        if (PEM_write_bio_PrivateKey_ex(bio, pkey, NULL, NULL, 0, NULL, NULL, libctx, propq) == 0) {
159            fprintf(stderr, "Failed to output PEM-encoded private key\n");
160            goto cleanup;
161        }
162    } else {
163        if (PEM_write_bio_Parameters(bio, pkey) == 0) {
164            fprintf(stderr, "Failed to output PEM-encoded params\n");
165            goto cleanup;
166        }
167    }
168    rv = 1;
169cleanup:
170    BIO_free(bio);
171    return rv;
172}
173