1/* 2 * Copyright 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#include <openssl/core.h> 11#include "bio_local.h" 12 13/*- 14 * Core BIO structure 15 * This is distinct from a BIO to prevent casting between the two which could 16 * lead to versioning problems. 17 */ 18struct ossl_core_bio_st { 19 CRYPTO_REF_COUNT ref_cnt; 20 CRYPTO_RWLOCK *ref_lock; 21 BIO *bio; 22}; 23 24static OSSL_CORE_BIO *core_bio_new(void) 25{ 26 OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb)); 27 28 if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) { 29 OPENSSL_free(cb); 30 return NULL; 31 } 32 cb->ref_cnt = 1; 33 return cb; 34} 35 36int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb) 37{ 38 int ref = 0; 39 40 return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock); 41} 42 43int ossl_core_bio_free(OSSL_CORE_BIO *cb) 44{ 45 int ref = 0, res = 1; 46 47 if (cb != NULL) { 48 CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock); 49 if (ref <= 0) { 50 res = BIO_free(cb->bio); 51 CRYPTO_THREAD_lock_free(cb->ref_lock); 52 OPENSSL_free(cb); 53 } 54 } 55 return res; 56} 57 58OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio) 59{ 60 OSSL_CORE_BIO *cb = core_bio_new(); 61 62 if (cb == NULL || !BIO_up_ref(bio)) { 63 ossl_core_bio_free(cb); 64 return NULL; 65 } 66 cb->bio = bio; 67 return cb; 68} 69 70static OSSL_CORE_BIO *core_bio_new_from_new_bio(BIO *bio) 71{ 72 OSSL_CORE_BIO *cb = NULL; 73 74 if (bio == NULL) 75 return NULL; 76 if ((cb = core_bio_new()) == NULL) { 77 BIO_free(bio); 78 return NULL; 79 } 80 cb->bio = bio; 81 return cb; 82} 83 84OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode) 85{ 86 return core_bio_new_from_new_bio(BIO_new_file(filename, mode)); 87} 88 89OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len) 90{ 91 return core_bio_new_from_new_bio(BIO_new_mem_buf(buf, len)); 92} 93 94int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen, 95 size_t *readbytes) 96{ 97 return BIO_read_ex(cb->bio, data, dlen, readbytes); 98} 99 100int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen, 101 size_t *written) 102{ 103 return BIO_write_ex(cb->bio, data, dlen, written); 104} 105 106int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size) 107{ 108 return BIO_gets(cb->bio, buf, size); 109} 110 111int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf) 112{ 113 return BIO_puts(cb->bio, buf); 114} 115 116long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg) 117{ 118 return BIO_ctrl(cb->bio, cmd, larg, parg); 119} 120 121int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args) 122{ 123 return BIO_vprintf(cb->bio, format, args); 124} 125