1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qopcuax509certificatesigningrequest.h"
5#include "openssl_symbols_p.h"
6
7#include "qopcuakeypair_p.h"
8#include "qopcuax509certificatesigningrequest_p.h"
9
10QT_BEGIN_NAMESPACE
11
12/*!
13 \class QOpcUaX509CertificateSigningRequest
14 \inmodule QtOpcUa
15 \since 5.14
16
17 \brief QOpcUaX509CertificateSigningRequest create a certificate signing request.
18
19 This class is currently available as a Technology Preview, and therefore the API
20 and functionality provided by the class may be subject to change at any time without
21 prior notice.
22
23 Before actually creating the singing request data, any extension needed for that
24 specific request has to be added. Current supported extensions are SubjectAlternativeName,
25 BasicConstrains, KeyUsage and ExtendedKeyUsage.
26
27 \code
28 // Generate key
29 QOpcUaKeyPair key;
30 key.generateRsaKey(QOpcUaKeyPair::RsaKeyStrength::Bits1024);
31
32 QOpcUaX509CertificateSigningRequest csr;
33
34 QOpcUaX509DistinguishedName dn;
35 dn.setEntry(QOpcUaX509DistinguishedName::Type::CommonName, "QtOpcUaViewer");
36 dn.setEntry(QOpcUaX509DistinguishedName::Type::CountryName, "DE");
37 dn.setEntry(QOpcUaX509DistinguishedName::Type::LocalityName, "Berlin");
38 dn.setEntry(QOpcUaX509DistinguishedName::Type::StateOrProvinceName, "Berlin");
39 dn.setEntry(QOpcUaX509DistinguishedName::Type::OrganizationName, "The Qt Company");
40 csr.setSubject(dn);
41
42 QOpcUaX509ExtensionSubjectAlternativeName *san = new QOpcUaX509ExtensionSubjectAlternativeName;
43 san->addData(QOpcUaX509ExtensionSubjectAlternativeName::Type::DNS, "foo.com");
44 san->addData(QOpcUaX509ExtensionSubjectAlternativeName::Type::DNS, "foo.com");
45 san->addData(QOpcUaX509ExtensionSubjectAlternativeName::Type::URI, "urn:foo.com:The%20Qt%20Company:QtOpcUaViewer");
46 san->setCritical(true);
47 csr.addExtension(san);
48
49 QOpcUaX509ExtensionBasicConstraints *bc = new QOpcUaX509ExtensionBasicConstraints;
50 bc->setCa(false);
51 bc->setCritical(true);
52 csr.addExtension(bc);
53
54 QOpcUaX509ExtensionKeyUsage *ku = new QOpcUaX509ExtensionKeyUsage;
55 ku->setCritical(true);
56 ku->setKeyUsage(QOpcUaX509ExtensionKeyUsage::KeyUsage::DigitalSignature);
57 ku->setKeyUsage(QOpcUaX509ExtensionKeyUsage::KeyUsage::NonRepudiation);
58 ku->setKeyUsage(QOpcUaX509ExtensionKeyUsage::KeyUsage::KeyEncipherment);
59 ku->setKeyUsage(QOpcUaX509ExtensionKeyUsage::KeyUsage::DataEncipherment);
60 ku->setKeyUsage(QOpcUaX509ExtensionKeyUsage::KeyUsage::CertificateSigning);
61 csr.addExtension(ku);
62
63 QOpcUaX509ExtensionExtendedKeyUsage *eku = new QOpcUaX509ExtensionExtendedKeyUsage;
64 eku->setCritical(true);
65 eku->setKeyUsage(QOpcUaX509ExtensionExtendedKeyUsage::KeyUsage::EmailProtection);
66 csr.addExtension(eku);
67
68 QByteArray csrData = csr.createRequest(key);
69 \endcode
70
71 \sa QOpcUaX509ExtensionSubjectAlternativeName, QOpcUaX509ExtensionBasicConstraints, QOpcUaX509ExtensionKeyUsage, QOpcUaX509ExtensionKeyUsage
72*/
73
74/*!
75 \enum QOpcUaX509CertificateSigningRequest::MessageDigest
76
77 This enum type specifies the message digest to be used.
78
79 \value SHA256
80 Using the SHA256 message digest
81*/
82
83/*!
84 \enum QOpcUaX509CertificateSigningRequest::Encoding
85
86 This enum type specifies the encoding of the generated certificate siging request.
87
88 \value PEM
89 Using PEM encoding
90 \value DER
91 Using DER encoding
92*/
93
94/*!
95 Creates an empty certificate signing request.
96*/
97QOpcUaX509CertificateSigningRequest::QOpcUaX509CertificateSigningRequest()
98 : d_ptr(new QOpcUaX509CertificateSigningRequestPrivate)
99{
100 setEncoding(Encoding::PEM);
101}
102
103/*!
104 Destroys the request and frees all extensions.
105*/
106QOpcUaX509CertificateSigningRequest::~QOpcUaX509CertificateSigningRequest()
107{
108 delete d_ptr;
109}
110
111/*!
112 Sets the used message digest to \a digest.
113 The default message digest is SHA256.
114*/
115void QOpcUaX509CertificateSigningRequest::setMessageDigest(QOpcUaX509CertificateSigningRequest::MessageDigest digest)
116{
117 Q_D(QOpcUaX509CertificateSigningRequest);
118 d->setMessageDigest(digest);
119}
120
121/*!
122 Returns the used message digest.
123*/
124QOpcUaX509CertificateSigningRequest::MessageDigest QOpcUaX509CertificateSigningRequest::messageDigest() const
125{
126 Q_D(const QOpcUaX509CertificateSigningRequest);
127 return d->messageDigest();
128}
129
130/*!
131 Returns the used request encoding.
132*/
133QOpcUaX509CertificateSigningRequest::Encoding QOpcUaX509CertificateSigningRequest::encoding() const
134{
135 Q_D(const QOpcUaX509CertificateSigningRequest);
136 return d->encoding();
137}
138
139/*!
140 Sets the used request encoding to \a encoding.
141 The default request encoding is PEM.
142*/
143void QOpcUaX509CertificateSigningRequest::setEncoding(QOpcUaX509CertificateSigningRequest::Encoding encoding)
144{
145 Q_D(QOpcUaX509CertificateSigningRequest);
146 d->setEncoding(encoding);
147}
148
149/*!
150 Adds a certificate extension to the request.
151
152 The ownership of the \a extension object will be transferred to this class.
153
154 \sa QOpcUaX509ExtensionSubjectAlternativeName,
155 QOpcUaX509ExtensionBasicConstraints,
156 QOpcUaX509ExtensionKeyUsage,
157 QOpcUaX509ExtensionKeyUsage
158*/
159void QOpcUaX509CertificateSigningRequest::addExtension(QOpcUaX509Extension *extension)
160{
161 Q_D(QOpcUaX509CertificateSigningRequest);
162 d->addExtension(extension);
163}
164
165/*!
166 Sets the \a subject for this request.
167 Without a subject it is not possible to generate the request.
168*/
169void QOpcUaX509CertificateSigningRequest::setSubject(const QOpcUaX509DistinguishedName &subject)
170{
171 Q_D(QOpcUaX509CertificateSigningRequest);
172 d->setSubject(subject);
173}
174
175/*!
176 Returns the subject of this request.
177*/
178const QOpcUaX509DistinguishedName &QOpcUaX509CertificateSigningRequest::subject() const
179{
180 Q_D(const QOpcUaX509CertificateSigningRequest);
181 return d->subject();
182}
183
184/*!
185 Creates a certificate signing request to be the to a CA for signing.
186 The private key in \a privateKey is used to sign the request.
187 The request data is returned as a byte array in the encoding set by setEncoding().
188*/
189QByteArray QOpcUaX509CertificateSigningRequest::createRequest(const QOpcUaKeyPair &privateKey)
190{
191 Q_D(QOpcUaX509CertificateSigningRequest);
192 return d->createRequest(privateKey);
193}
194
195/*!
196 Creates a self-signed certificate from this request for immediate use.
197 The private key in \a privateKey is used to sign the request.
198 A validity in days can be specified in \a validityInDays.
199 The request data is returned as a byte array in the encoding set by setEncoding().
200*/
201QByteArray QOpcUaX509CertificateSigningRequest::createSelfSignedCertificate(const QOpcUaKeyPair &privateKey, int validityInDays)
202{
203 Q_D(QOpcUaX509CertificateSigningRequest);
204 return d->createSelfSignedCertificate(privateKey, validityInDays);
205}
206
207QT_END_NAMESPACE
208

source code of qtopcua/src/opcua/x509/qopcuax509certificatesigningrequest.cpp