File: BioByteArray.cpp

package info (click to toggle)
xca 2.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,328 kB
  • sloc: cpp: 30,584; sh: 341; xml: 74; makefile: 56; python: 34
file content (161 lines) | stat: -rw-r--r-- 2,981 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* vi: set sw=4 ts=4:
 *
 * Copyright (C) 2020 Christian Hohnstaedt.
 *
 * All rights reserved.
 */

#include "BioByteArray.h"
#include "func_base.h"
#include <QDebug>

BioByteArray::BioByteArray(const BIGNUM *bn, int bits)
{
	int len = (bits+7) >> 3;
	qDebug() << bits << len;
	if (!bn)
		return;
	store.resize(BN_num_bytes(bn));
	BN_bn2bin(bn, (unsigned char *)store.data());
	openssl_error();
	if (store.size() > 0 && (unsigned char)store[0] >= 0x80)
		store.prepend('\0');
	if (len > 0 && store.size() < len)
		store.prepend(len - store.size(), 0);
}

void BioByteArray::set(const QByteArray &qba)
{
	if (read_write) {
		char buf[1024];
		qWarning() << "BioByteArray already in use";
		while (BIO_read(read_write, buf, sizeof buf) > 0)
			;
		memset(buf, 0, sizeof buf);
	}
	store.fill(0);
	store.clear();
	add(qba);
}

void BioByteArray::add(const QByteArray &qba)
{
	if (read_only) {
		qWarning() << "BioByteArray is read-only";
		return;
	}
	if (read_write)
		biowrite(qba);
	else
		store += qba;
}

void BioByteArray::biowrite(const QByteArray &qba)
{
	BIO_write(read_write, qba.data(), qba.size());
}

void BioByteArray::cleanse_and_free(BIO *bio)
{
	if (!bio)
		return;
	char *p;
	long l = BIO_get_mem_data(bio, &p);
	OPENSSL_cleanse(p, l);
	BIO_free(bio);
}

BioByteArray::~BioByteArray()
{
	store.fill(0);
	store.clear();
	cleanse_and_free(read_write);
	if (read_only)
		BIO_free(read_only);
}

BIO *BioByteArray::bio()
{
	if (!read_write) {
		read_write = BIO_new(BIO_s_mem());
		Q_CHECK_PTR(read_write);
		biowrite(store);
		store.fill(0);
		store.clear();
	}
	return read_write;
}

BIO *BioByteArray::ro()
{
	if (!read_only)
		read_only = BIO_new_mem_buf(
			(void*)store.constData(), store.length());
	Q_CHECK_PTR(read_only);
	return read_only;
}

QByteArray BioByteArray::byteArray() const
{
	if (read_only || !read_write)
		return store;
	/* "read_write" Bio may differ from "store" */
	const char *p;
	int l = BIO_get_mem_data(read_write, &p);
	return QByteArray(p, l);
}

int BioByteArray::size() const
{
	if (read_only || !read_write)
		return store.size();
	/* "read_write" Bio may differ from "store" */
	const char *p;
	return BIO_get_mem_data(read_write, &p);
}

QString BioByteArray::qstring() const
{
	return QString::fromUtf8(byteArray().constData());
}

BioByteArray::operator BIO*()
{
	return bio();
}

BioByteArray::operator QByteArray()
{
	return byteArray();
}

BioByteArray &BioByteArray::operator = (const BioByteArray &other)
{
	set(other.byteArray());
	return *this;
}

BioByteArray &BioByteArray::operator = (const QByteArray &qba)
{
	set(qba);
	return *this;
}

BioByteArray &BioByteArray::operator += (const BioByteArray &other)
{
	add(other.byteArray());
	return *this;
}

BioByteArray &BioByteArray::operator += (const QByteArray &qba)
{
	add(qba);
	return *this;
}

QString BioByteArray::base64UrlEncode() const
{
	return QString::fromLatin1(byteArray().toBase64(
			QByteArray::Base64UrlEncoding |
			QByteArray::OmitTrailingEquals));
}