| /* |
| * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. |
| * |
| * Licensed under the Apache License 2.0 (the "License"). You may not use |
| * this file except in compliance with the License. You can obtain a copy |
| * in the file LICENSE in the source distribution or at |
| * https://www.openssl.org/source/license.html |
| */ |
| |
| #include <openssl/core.h> |
| #include "bio_local.h" |
| |
| /*- |
| * Core BIO structure |
| * This is distinct from a BIO to prevent casting between the two which could |
| * lead to versioning problems. |
| */ |
| struct ossl_core_bio_st { |
| CRYPTO_REF_COUNT ref_cnt; |
| CRYPTO_RWLOCK *ref_lock; |
| BIO *bio; |
| }; |
| |
| static OSSL_CORE_BIO *core_bio_new(void) |
| { |
| OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb)); |
| |
| if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) { |
| OPENSSL_free(cb); |
| return NULL; |
| } |
| cb->ref_cnt = 1; |
| return cb; |
| } |
| |
| int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb) |
| { |
| int ref = 0; |
| |
| return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock); |
| } |
| |
| int ossl_core_bio_free(OSSL_CORE_BIO *cb) |
| { |
| int ref = 0, res = 1; |
| |
| if (cb != NULL) { |
| CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock); |
| if (ref <= 0) { |
| res = BIO_free(cb->bio); |
| CRYPTO_THREAD_lock_free(cb->ref_lock); |
| OPENSSL_free(cb); |
| } |
| } |
| return res; |
| } |
| |
| OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio) |
| { |
| OSSL_CORE_BIO *cb = core_bio_new(); |
| |
| if (cb == NULL || !BIO_up_ref(bio)) { |
| ossl_core_bio_free(cb); |
| return NULL; |
| } |
| cb->bio = bio; |
| return cb; |
| } |
| |
| static OSSL_CORE_BIO *core_bio_new_from_new_bio(BIO *bio) |
| { |
| OSSL_CORE_BIO *cb = NULL; |
| |
| if (bio == NULL) |
| return NULL; |
| if ((cb = core_bio_new()) == NULL) { |
| BIO_free(bio); |
| return NULL; |
| } |
| cb->bio = bio; |
| return cb; |
| } |
| |
| OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode) |
| { |
| return core_bio_new_from_new_bio(BIO_new_file(filename, mode)); |
| } |
| |
| OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len) |
| { |
| return core_bio_new_from_new_bio(BIO_new_mem_buf(buf, len)); |
| } |
| |
| int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen, |
| size_t *readbytes) |
| { |
| return BIO_read_ex(cb->bio, data, dlen, readbytes); |
| } |
| |
| int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen, |
| size_t *written) |
| { |
| return BIO_write_ex(cb->bio, data, dlen, written); |
| } |
| |
| int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size) |
| { |
| return BIO_gets(cb->bio, buf, size); |
| } |
| |
| int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf) |
| { |
| return BIO_puts(cb->bio, buf); |
| } |
| |
| long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg) |
| { |
| return BIO_ctrl(cb->bio, cmd, larg, parg); |
| } |
| |
| int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args) |
| { |
| return BIO_vprintf(cb->bio, format, args); |
| } |