/src/openssl30/crypto/asn1/i2d_evp.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2022 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 |  |  * 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/evp.h> | 
| 19 |  | #include <openssl/encoder.h> | 
| 20 |  | #include <openssl/buffer.h> | 
| 21 |  | #include <openssl/x509.h> | 
| 22 |  | #include <openssl/rsa.h>         /* For i2d_RSAPublicKey */ | 
| 23 |  | #include <openssl/dsa.h>         /* For i2d_DSAPublicKey */ | 
| 24 |  | #include <openssl/ec.h>          /* For i2o_ECPublicKey */ | 
| 25 |  | #include "crypto/asn1.h" | 
| 26 |  | #include "crypto/evp.h" | 
| 27 |  |  | 
| 28 |  | struct type_and_structure_st { | 
| 29 |  |     const char *output_type; | 
| 30 |  |     const char *output_structure; | 
| 31 |  | }; | 
| 32 |  |  | 
| 33 |  | static int i2d_provided(const EVP_PKEY *a, int selection, | 
| 34 |  |                         const struct type_and_structure_st *output_info, | 
| 35 |  |                         unsigned char **pp) | 
| 36 | 2.41k | { | 
| 37 | 2.41k |     OSSL_ENCODER_CTX *ctx = NULL; | 
| 38 | 2.41k |     int ret; | 
| 39 |  |  | 
| 40 | 2.41k |     for (ret = -1; | 
| 41 | 5.17k |          ret == -1 && output_info->output_type != NULL; | 
| 42 | 2.75k |          output_info++) { | 
| 43 |  |         /* | 
| 44 |  |          * The i2d_ calls don't take a boundary length for *pp.  However, | 
| 45 |  |          * OSSL_ENCODER_to_data() needs one, so we make one up.  Because | 
| 46 |  |          * OSSL_ENCODER_to_data() decrements this number by the amount of | 
| 47 |  |          * bytes written, we need to calculate the length written further | 
| 48 |  |          * down, when pp != NULL. | 
| 49 |  |          */ | 
| 50 | 2.75k |         size_t len = INT_MAX; | 
| 51 | 2.75k |         int pp_was_NULL = (pp == NULL || *pp == NULL); | 
| 52 |  |  | 
| 53 | 2.75k |         ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, | 
| 54 | 2.75k |                                             output_info->output_type, | 
| 55 | 2.75k |                                             output_info->output_structure, | 
| 56 | 2.75k |                                             NULL); | 
| 57 | 2.75k |         if (ctx == NULL) | 
| 58 | 0 |             return -1; | 
| 59 | 2.75k |         if (OSSL_ENCODER_to_data(ctx, pp, &len)) { | 
| 60 | 2.12k |             if (pp_was_NULL) | 
| 61 | 2.12k |                 ret = (int)len; | 
| 62 | 0 |             else | 
| 63 | 0 |                 ret = INT_MAX - (int)len; | 
| 64 | 2.12k |         } | 
| 65 | 2.75k |         OSSL_ENCODER_CTX_free(ctx); | 
| 66 | 2.75k |         ctx = NULL; | 
| 67 | 2.75k |     } | 
| 68 |  |  | 
| 69 | 2.41k |     if (ret == -1) | 
| 70 | 2.41k |         ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); | 
| 71 | 2.41k |     return ret; | 
| 72 | 2.41k | } | 
| 73 |  |  | 
| 74 |  | int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp) | 
| 75 | 0 | { | 
| 76 | 0 |     if (evp_pkey_is_provided(a)) { | 
| 77 | 0 |         static const struct type_and_structure_st output_info[] = { | 
| 78 | 0 |             { "DER", "type-specific" }, | 
| 79 | 0 |             { NULL, } | 
| 80 | 0 |         }; | 
| 81 |  | 
 | 
| 82 | 0 |         return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_info, pp); | 
| 83 | 0 |     } | 
| 84 | 0 |     if (a->ameth != NULL && a->ameth->param_encode != NULL) | 
| 85 | 0 |         return a->ameth->param_encode(a, pp); | 
| 86 | 0 |     ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); | 
| 87 | 0 |     return -1; | 
| 88 | 0 | } | 
| 89 |  |  | 
| 90 |  | int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey) | 
| 91 | 0 | { | 
| 92 | 0 |     return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey); | 
| 93 | 0 | } | 
| 94 |  |  | 
| 95 |  | int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp) | 
| 96 | 2.55k | { | 
| 97 | 2.55k |     if (evp_pkey_is_provided(a)) { | 
| 98 | 2.41k |         static const struct type_and_structure_st output_info[] = { | 
| 99 | 2.41k |             { "DER", "type-specific" }, | 
| 100 | 2.41k |             { "DER", "PrivateKeyInfo" }, | 
| 101 | 2.41k |             { NULL, } | 
| 102 | 2.41k |         }; | 
| 103 |  |  | 
| 104 | 2.41k |         return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp); | 
| 105 | 2.41k |     } | 
| 106 | 139 |     if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) { | 
| 107 | 133 |         return a->ameth->old_priv_encode(a, pp); | 
| 108 | 133 |     } | 
| 109 | 6 |     if (a->ameth != NULL && a->ameth->priv_encode != NULL) { | 
| 110 | 6 |         PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); | 
| 111 | 6 |         int ret = 0; | 
| 112 |  |  | 
| 113 | 6 |         if (p8 != NULL) { | 
| 114 | 6 |             ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); | 
| 115 | 6 |             PKCS8_PRIV_KEY_INFO_free(p8); | 
| 116 | 6 |         } | 
| 117 | 6 |         return ret; | 
| 118 | 6 |     } | 
| 119 | 6 |     ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); | 
| 120 | 0 |     return -1; | 
| 121 | 6 | } | 
| 122 |  |  | 
| 123 |  | int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp) | 
| 124 | 0 | { | 
| 125 | 0 |     if (evp_pkey_is_provided(a)) { | 
| 126 | 0 |         static const struct type_and_structure_st output_info[] = { | 
| 127 | 0 |             { "DER", "type-specific" }, | 
| 128 | 0 |             { "blob", NULL },    /* for EC */ | 
| 129 | 0 |             { NULL, } | 
| 130 | 0 |         }; | 
| 131 |  | 
 | 
| 132 | 0 |         return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp); | 
| 133 | 0 |     } | 
| 134 | 0 |     switch (EVP_PKEY_get_base_id(a)) { | 
| 135 | 0 |     case EVP_PKEY_RSA: | 
| 136 | 0 |         return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp); | 
| 137 | 0 | #ifndef OPENSSL_NO_DSA | 
| 138 | 0 |     case EVP_PKEY_DSA: | 
| 139 | 0 |         return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); | 
| 140 | 0 | #endif | 
| 141 | 0 | #ifndef OPENSSL_NO_EC | 
| 142 | 0 |     case EVP_PKEY_EC: | 
| 143 | 0 |         return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); | 
| 144 | 0 | #endif | 
| 145 | 0 |     default: | 
| 146 | 0 |         ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); | 
| 147 | 0 |         return -1; | 
| 148 | 0 |     } | 
| 149 | 0 | } |