1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "bio_local.h" 11e1051a39Sopenharmony_ci#include "internal/thread_once.h" 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ciCRYPTO_RWLOCK *bio_type_lock = NULL; 14e1051a39Sopenharmony_cistatic CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT; 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(do_bio_type_init) 17e1051a39Sopenharmony_ci{ 18e1051a39Sopenharmony_ci bio_type_lock = CRYPTO_THREAD_lock_new(); 19e1051a39Sopenharmony_ci return bio_type_lock != NULL; 20e1051a39Sopenharmony_ci} 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ciint BIO_get_new_index(void) 23e1051a39Sopenharmony_ci{ 24e1051a39Sopenharmony_ci static CRYPTO_REF_COUNT bio_count = BIO_TYPE_START; 25e1051a39Sopenharmony_ci int newval; 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_ci if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) { 28e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); 29e1051a39Sopenharmony_ci return -1; 30e1051a39Sopenharmony_ci } 31e1051a39Sopenharmony_ci if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock)) 32e1051a39Sopenharmony_ci return -1; 33e1051a39Sopenharmony_ci return newval; 34e1051a39Sopenharmony_ci} 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ciBIO_METHOD *BIO_meth_new(int type, const char *name) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD)); 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci if (biom == NULL 41e1051a39Sopenharmony_ci || (biom->name = OPENSSL_strdup(name)) == NULL) { 42e1051a39Sopenharmony_ci OPENSSL_free(biom); 43e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); 44e1051a39Sopenharmony_ci return NULL; 45e1051a39Sopenharmony_ci } 46e1051a39Sopenharmony_ci biom->type = type; 47e1051a39Sopenharmony_ci return biom; 48e1051a39Sopenharmony_ci} 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_civoid BIO_meth_free(BIO_METHOD *biom) 51e1051a39Sopenharmony_ci{ 52e1051a39Sopenharmony_ci if (biom != NULL) { 53e1051a39Sopenharmony_ci OPENSSL_free(biom->name); 54e1051a39Sopenharmony_ci OPENSSL_free(biom); 55e1051a39Sopenharmony_ci } 56e1051a39Sopenharmony_ci} 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ciint (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int) 59e1051a39Sopenharmony_ci{ 60e1051a39Sopenharmony_ci return biom->bwrite_old; 61e1051a39Sopenharmony_ci} 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ciint (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t, 64e1051a39Sopenharmony_ci size_t *) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci return biom->bwrite; 67e1051a39Sopenharmony_ci} 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci/* Conversion for old style bwrite to new style */ 70e1051a39Sopenharmony_ciint bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written) 71e1051a39Sopenharmony_ci{ 72e1051a39Sopenharmony_ci int ret; 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci if (datal > INT_MAX) 75e1051a39Sopenharmony_ci datal = INT_MAX; 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_ci ret = bio->method->bwrite_old(bio, data, (int)datal); 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci if (ret <= 0) { 80e1051a39Sopenharmony_ci *written = 0; 81e1051a39Sopenharmony_ci return ret; 82e1051a39Sopenharmony_ci } 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ci *written = (size_t)ret; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci return 1; 87e1051a39Sopenharmony_ci} 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ciint BIO_meth_set_write(BIO_METHOD *biom, 90e1051a39Sopenharmony_ci int (*bwrite) (BIO *, const char *, int)) 91e1051a39Sopenharmony_ci{ 92e1051a39Sopenharmony_ci biom->bwrite_old = bwrite; 93e1051a39Sopenharmony_ci biom->bwrite = bwrite_conv; 94e1051a39Sopenharmony_ci return 1; 95e1051a39Sopenharmony_ci} 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ciint BIO_meth_set_write_ex(BIO_METHOD *biom, 98e1051a39Sopenharmony_ci int (*bwrite) (BIO *, const char *, size_t, size_t *)) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci biom->bwrite_old = NULL; 101e1051a39Sopenharmony_ci biom->bwrite = bwrite; 102e1051a39Sopenharmony_ci return 1; 103e1051a39Sopenharmony_ci} 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ciint (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int) 106e1051a39Sopenharmony_ci{ 107e1051a39Sopenharmony_ci return biom->bread_old; 108e1051a39Sopenharmony_ci} 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ciint (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *) 111e1051a39Sopenharmony_ci{ 112e1051a39Sopenharmony_ci return biom->bread; 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci/* Conversion for old style bread to new style */ 116e1051a39Sopenharmony_ciint bread_conv(BIO *bio, char *data, size_t datal, size_t *readbytes) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci int ret; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (datal > INT_MAX) 121e1051a39Sopenharmony_ci datal = INT_MAX; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci ret = bio->method->bread_old(bio, data, (int)datal); 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci if (ret <= 0) { 126e1051a39Sopenharmony_ci *readbytes = 0; 127e1051a39Sopenharmony_ci return ret; 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci *readbytes = (size_t)ret; 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ci return 1; 133e1051a39Sopenharmony_ci} 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ciint BIO_meth_set_read(BIO_METHOD *biom, 136e1051a39Sopenharmony_ci int (*bread) (BIO *, char *, int)) 137e1051a39Sopenharmony_ci{ 138e1051a39Sopenharmony_ci biom->bread_old = bread; 139e1051a39Sopenharmony_ci biom->bread = bread_conv; 140e1051a39Sopenharmony_ci return 1; 141e1051a39Sopenharmony_ci} 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ciint BIO_meth_set_read_ex(BIO_METHOD *biom, 144e1051a39Sopenharmony_ci int (*bread) (BIO *, char *, size_t, size_t *)) 145e1051a39Sopenharmony_ci{ 146e1051a39Sopenharmony_ci biom->bread_old = NULL; 147e1051a39Sopenharmony_ci biom->bread = bread; 148e1051a39Sopenharmony_ci return 1; 149e1051a39Sopenharmony_ci} 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ciint (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *) 152e1051a39Sopenharmony_ci{ 153e1051a39Sopenharmony_ci return biom->bputs; 154e1051a39Sopenharmony_ci} 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ciint BIO_meth_set_puts(BIO_METHOD *biom, 157e1051a39Sopenharmony_ci int (*bputs) (BIO *, const char *)) 158e1051a39Sopenharmony_ci{ 159e1051a39Sopenharmony_ci biom->bputs = bputs; 160e1051a39Sopenharmony_ci return 1; 161e1051a39Sopenharmony_ci} 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ciint (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int) 164e1051a39Sopenharmony_ci{ 165e1051a39Sopenharmony_ci return biom->bgets; 166e1051a39Sopenharmony_ci} 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ciint BIO_meth_set_gets(BIO_METHOD *biom, 169e1051a39Sopenharmony_ci int (*bgets) (BIO *, char *, int)) 170e1051a39Sopenharmony_ci{ 171e1051a39Sopenharmony_ci biom->bgets = bgets; 172e1051a39Sopenharmony_ci return 1; 173e1051a39Sopenharmony_ci} 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_cilong (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *) 176e1051a39Sopenharmony_ci{ 177e1051a39Sopenharmony_ci return biom->ctrl; 178e1051a39Sopenharmony_ci} 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ciint BIO_meth_set_ctrl(BIO_METHOD *biom, 181e1051a39Sopenharmony_ci long (*ctrl) (BIO *, int, long, void *)) 182e1051a39Sopenharmony_ci{ 183e1051a39Sopenharmony_ci biom->ctrl = ctrl; 184e1051a39Sopenharmony_ci return 1; 185e1051a39Sopenharmony_ci} 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_ciint (*BIO_meth_get_create(const BIO_METHOD *biom)) (BIO *) 188e1051a39Sopenharmony_ci{ 189e1051a39Sopenharmony_ci return biom->create; 190e1051a39Sopenharmony_ci} 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ciint BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)) 193e1051a39Sopenharmony_ci{ 194e1051a39Sopenharmony_ci biom->create = create; 195e1051a39Sopenharmony_ci return 1; 196e1051a39Sopenharmony_ci} 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ciint (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *) 199e1051a39Sopenharmony_ci{ 200e1051a39Sopenharmony_ci return biom->destroy; 201e1051a39Sopenharmony_ci} 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_ciint BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)) 204e1051a39Sopenharmony_ci{ 205e1051a39Sopenharmony_ci biom->destroy = destroy; 206e1051a39Sopenharmony_ci return 1; 207e1051a39Sopenharmony_ci} 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_cilong (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) (BIO *, int, BIO_info_cb *) 210e1051a39Sopenharmony_ci{ 211e1051a39Sopenharmony_ci return biom->callback_ctrl; 212e1051a39Sopenharmony_ci} 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ciint BIO_meth_set_callback_ctrl(BIO_METHOD *biom, 215e1051a39Sopenharmony_ci long (*callback_ctrl) (BIO *, int, 216e1051a39Sopenharmony_ci BIO_info_cb *)) 217e1051a39Sopenharmony_ci{ 218e1051a39Sopenharmony_ci biom->callback_ctrl = callback_ctrl; 219e1051a39Sopenharmony_ci return 1; 220e1051a39Sopenharmony_ci} 221