1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2020 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 #include "BioByteArray.h"
9 #include <QDebug>
10 
set(const QByteArray & qba)11 void BioByteArray::set(const QByteArray &qba)
12 {
13 	if (read_write) {
14 		char buf[1024];
15 		qWarning() << "BioByteArray already in use";
16 		while (BIO_read(read_write, buf, sizeof buf) > 0)
17 			;
18 		memset(buf, 0, sizeof buf);
19 	}
20 	add(qba);
21 }
22 
add(const QByteArray & qba)23 void BioByteArray::add(const QByteArray &qba)
24 {
25 	if (read_only) {
26 		qWarning() << "BioByteArray is read-only";
27 		return;
28 	}
29 	if (read_write)
30 		biowrite(qba);
31 	else
32 		store += qba;
33 }
34 
biowrite(const QByteArray & qba)35 void BioByteArray::biowrite(const QByteArray &qba)
36 {
37 	BIO_write(read_write, qba.data(), qba.size());
38 }
39 
cleanse_and_free(BIO * bio)40 void BioByteArray::cleanse_and_free(BIO *bio)
41 {
42 	if (!bio)
43 		return;
44 	char *p;
45 	long l = BIO_get_mem_data(bio, &p);
46 	OPENSSL_cleanse(p, l);
47 	BIO_free(bio);
48 }
49 
~BioByteArray()50 BioByteArray::~BioByteArray()
51 {
52 	store.fill(0);
53 	store.clear();
54 	cleanse_and_free(read_write);
55 	if (read_only)
56 		BIO_free(read_only);
57 }
58 
bio()59 BIO *BioByteArray::bio()
60 {
61 	if (!read_write) {
62 		read_write = BIO_new(BIO_s_mem());
63 		biowrite(store);
64 		store.fill(0);
65 		store.clear();
66 	}
67 	return read_write;
68 }
69 
ro()70 BIO *BioByteArray::ro()
71 {
72 	if (!read_only)
73 		read_only = BIO_new_mem_buf(
74 			(void*)store.constData(), store.length());
75 	return read_only;
76 }
77 
byteArray() const78 QByteArray BioByteArray::byteArray() const
79 {
80 	if (read_only || !read_write)
81 		return store;
82 	/* "read_write" Bio may differ from "store" */
83 	const char *p;
84 	int l = BIO_get_mem_data(read_write, &p);
85 	return QByteArray(p, l);
86 }
87 
size() const88 int BioByteArray::size() const
89 {
90 	if (read_only || !read_write)
91 		return store.size();
92 	/* "read_write" Bio may differ from "store" */
93 	const char *p;
94 	return BIO_get_mem_data(read_write, &p);
95 }
96 
qstring() const97 QString BioByteArray::qstring() const
98 {
99 	return QString::fromUtf8(byteArray().constData());
100 }
101 
operator BIO*()102 BioByteArray::operator BIO*()
103 {
104 	return bio();
105 }
106 
operator QByteArray()107 BioByteArray::operator QByteArray()
108 {
109 	return byteArray();
110 }
111 
operator =(const BioByteArray & other)112 BioByteArray &BioByteArray::operator = (const BioByteArray &other)
113 {
114 	set(other.byteArray());
115 	return *this;
116 }
117 
operator =(const QByteArray & qba)118 BioByteArray &BioByteArray::operator = (const QByteArray &qba)
119 {
120 	set(qba);
121 	return *this;
122 }
123 
operator +=(const BioByteArray & other)124 BioByteArray &BioByteArray::operator += (const BioByteArray &other)
125 {
126 	add(other.byteArray());
127 	return *this;
128 }
129 
operator +=(const QByteArray & qba)130 BioByteArray &BioByteArray::operator += (const QByteArray &qba)
131 {
132 	add(qba);
133 	return *this;
134 }
135