/src/openssl30/crypto/dh/dh_asn1.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
| 5 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  |  * in the file LICENSE in the source distribution or at | 
| 7 |  |  * https://www.openssl.org/source/license.html | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | /* | 
| 11 |  |  * DH low level APIs are deprecated for public use, but still ok for | 
| 12 |  |  * internal use. | 
| 13 |  |  */ | 
| 14 |  | #include "internal/deprecated.h" | 
| 15 |  |  | 
| 16 |  | #include <stdio.h> | 
| 17 |  | #include "internal/cryptlib.h" | 
| 18 |  | #include <openssl/bn.h> | 
| 19 |  | #include "dh_local.h" | 
| 20 |  | #include <openssl/objects.h> | 
| 21 |  | #include <openssl/asn1t.h> | 
| 22 |  | #include "crypto/dh.h" | 
| 23 |  |  | 
| 24 |  | /* Override the default free and new methods */ | 
| 25 |  | static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, | 
| 26 |  |                  void *exarg) | 
| 27 | 158k | { | 
| 28 | 158k |     if (operation == ASN1_OP_NEW_PRE) { | 
| 29 | 52.4k |         *pval = (ASN1_VALUE *)DH_new(); | 
| 30 | 52.4k |         if (*pval != NULL) | 
| 31 | 52.4k |             return 2; | 
| 32 | 0 |         return 0; | 
| 33 | 105k |     } else if (operation == ASN1_OP_FREE_PRE) { | 
| 34 | 45.0k |         DH_free((DH *)*pval); | 
| 35 | 45.0k |         *pval = NULL; | 
| 36 | 45.0k |         return 2; | 
| 37 | 60.8k |     } else if (operation == ASN1_OP_D2I_POST) { | 
| 38 | 7.49k |         DH *dh = (DH *)*pval; | 
| 39 |  |  | 
| 40 | 7.49k |         DH_clear_flags(dh, DH_FLAG_TYPE_MASK); | 
| 41 | 7.49k |         DH_set_flags(dh, DH_FLAG_TYPE_DH); | 
| 42 | 7.49k |         ossl_dh_cache_named_group(dh); | 
| 43 | 7.49k |         dh->dirty_cnt++; | 
| 44 | 7.49k |     } | 
| 45 | 60.8k |     return 1; | 
| 46 | 158k | } | 
| 47 |  |  | 
| 48 |  | ASN1_SEQUENCE_cb(DHparams, dh_cb) = { | 
| 49 |  |         ASN1_SIMPLE(DH, params.p, BIGNUM), | 
| 50 |  |         ASN1_SIMPLE(DH, params.g, BIGNUM), | 
| 51 |  |         ASN1_OPT_EMBED(DH, length, ZINT32), | 
| 52 |  | } ASN1_SEQUENCE_END_cb(DH, DHparams) | 
| 53 |  |  | 
| 54 |  | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DH, DHparams, DHparams) | 
| 55 |  |  | 
| 56 |  | /* | 
| 57 |  |  * Internal only structures for handling X9.42 DH: this gets translated to or | 
| 58 |  |  * from a DH structure straight away. | 
| 59 |  |  */ | 
| 60 |  |  | 
| 61 |  | typedef struct { | 
| 62 |  |     ASN1_BIT_STRING *seed; | 
| 63 |  |     BIGNUM *counter; | 
| 64 |  | } int_dhvparams; | 
| 65 |  |  | 
| 66 |  | typedef struct { | 
| 67 |  |     BIGNUM *p; | 
| 68 |  |     BIGNUM *q; | 
| 69 |  |     BIGNUM *g; | 
| 70 |  |     BIGNUM *j; | 
| 71 |  |     int_dhvparams *vparams; | 
| 72 |  | } int_dhx942_dh; | 
| 73 |  |  | 
| 74 |  | ASN1_SEQUENCE(DHvparams) = { | 
| 75 |  |         ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), | 
| 76 |  |         ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) | 
| 77 |  | } static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams) | 
| 78 |  |  | 
| 79 |  | ASN1_SEQUENCE(DHxparams) = { | 
| 80 |  |         ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM), | 
| 81 |  |         ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM), | 
| 82 |  |         ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM), | 
| 83 |  |         ASN1_OPT(int_dhx942_dh, j, BIGNUM), | 
| 84 |  |         ASN1_OPT(int_dhx942_dh, vparams, DHvparams), | 
| 85 |  | } static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams) | 
| 86 |  |  | 
| 87 |  | int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a, | 
| 88 |  |                            const unsigned char **pp, long length); | 
| 89 |  | int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp); | 
| 90 |  |  | 
| 91 |  | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(int_dhx942_dh, DHxparams, int_dhx) | 
| 92 |  |  | 
| 93 |  | DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) | 
| 94 | 54.7k | { | 
| 95 | 54.7k |     FFC_PARAMS *params; | 
| 96 | 54.7k |     int_dhx942_dh *dhx = NULL; | 
| 97 | 54.7k |     DH *dh = NULL; | 
| 98 |  |  | 
| 99 | 54.7k |     dh = DH_new(); | 
| 100 | 54.7k |     if (dh == NULL) | 
| 101 | 0 |         return NULL; | 
| 102 | 54.7k |     dhx = d2i_int_dhx(NULL, pp, length); | 
| 103 | 54.7k |     if (dhx == NULL) { | 
| 104 | 42.4k |         DH_free(dh); | 
| 105 | 42.4k |         return NULL; | 
| 106 | 42.4k |     } | 
| 107 |  |  | 
| 108 | 12.2k |     if (a != NULL) { | 
| 109 | 0 |         DH_free(*a); | 
| 110 | 0 |         *a = dh; | 
| 111 | 0 |     } | 
| 112 |  |  | 
| 113 | 12.2k |     params = &dh->params; | 
| 114 | 12.2k |     DH_set0_pqg(dh, dhx->p, dhx->q, dhx->g); | 
| 115 | 12.2k |     ossl_ffc_params_set0_j(params, dhx->j); | 
| 116 |  |  | 
| 117 | 12.2k |     if (dhx->vparams != NULL) { | 
| 118 |  |         /* The counter has a maximum value of 4 * numbits(p) - 1 */ | 
| 119 | 111 |         size_t counter = (size_t)BN_get_word(dhx->vparams->counter); | 
| 120 | 111 |         ossl_ffc_params_set_validate_params(params, dhx->vparams->seed->data, | 
| 121 | 111 |                                             dhx->vparams->seed->length, | 
| 122 | 111 |                                             counter); | 
| 123 | 111 |         ASN1_BIT_STRING_free(dhx->vparams->seed); | 
| 124 | 111 |         BN_free(dhx->vparams->counter); | 
| 125 | 111 |         OPENSSL_free(dhx->vparams); | 
| 126 | 111 |         dhx->vparams = NULL; | 
| 127 | 111 |     } | 
| 128 |  |  | 
| 129 | 12.2k |     OPENSSL_free(dhx); | 
| 130 | 12.2k |     DH_clear_flags(dh, DH_FLAG_TYPE_MASK); | 
| 131 | 12.2k |     DH_set_flags(dh, DH_FLAG_TYPE_DHX); | 
| 132 | 12.2k |     return dh; | 
| 133 | 54.7k | } | 
| 134 |  |  | 
| 135 |  | int i2d_DHxparams(const DH *dh, unsigned char **pp) | 
| 136 | 126 | { | 
| 137 | 126 |     int ret = 0; | 
| 138 | 126 |     int_dhx942_dh dhx; | 
| 139 | 126 |     int_dhvparams dhv = { NULL, NULL }; | 
| 140 | 126 |     ASN1_BIT_STRING seed; | 
| 141 | 126 |     size_t seedlen = 0; | 
| 142 | 126 |     const FFC_PARAMS *params = &dh->params; | 
| 143 | 126 |     int counter; | 
| 144 |  |  | 
| 145 | 126 |     ossl_ffc_params_get0_pqg(params, (const BIGNUM **)&dhx.p, | 
| 146 | 126 |                              (const BIGNUM **)&dhx.q, (const BIGNUM **)&dhx.g); | 
| 147 | 126 |     dhx.j = params->j; | 
| 148 | 126 |     ossl_ffc_params_get_validate_params(params, &seed.data, &seedlen, &counter); | 
| 149 | 126 |     seed.length = (int)seedlen; | 
| 150 |  |  | 
| 151 | 126 |     if (counter != -1 && seed.data != NULL && seed.length > 0) { | 
| 152 | 33 |         seed.flags = ASN1_STRING_FLAG_BITS_LEFT; | 
| 153 | 33 |         dhv.seed = &seed; | 
| 154 | 33 |         dhv.counter = BN_new(); | 
| 155 | 33 |         if (dhv.counter == NULL) | 
| 156 | 0 |             return 0; | 
| 157 | 33 |         if (!BN_set_word(dhv.counter, (BN_ULONG)counter)) | 
| 158 | 0 |             goto err; | 
| 159 | 33 |         dhx.vparams = &dhv; | 
| 160 | 93 |     } else { | 
| 161 | 93 |         dhx.vparams = NULL; | 
| 162 | 93 |     } | 
| 163 | 126 |     ret = i2d_int_dhx(&dhx, pp); | 
| 164 | 126 | err: | 
| 165 | 126 |     BN_free(dhv.counter); | 
| 166 | 126 |     return ret; | 
| 167 | 126 | } |