summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hartmann <peter.hartmann@nokia.com>2010-06-01 14:50:55 (GMT)
committerPeter Hartmann <peter.hartmann@nokia.com>2010-06-02 09:46:44 (GMT)
commit0f16c7ce8dcd6f4905d14875088c55148e41366a (patch)
treed0b6a19e3fe57b55711ff7a7b6c48e9a15f457e4
parentcd50f97a9f09eece645c9d7d01cb14c04521a915 (diff)
downloadQt-0f16c7ce8dcd6f4905d14875088c55148e41366a.zip
Qt-0f16c7ce8dcd6f4905d14875088c55148e41366a.tar.gz
Qt-0f16c7ce8dcd6f4905d14875088c55148e41366a.tar.bz2
QSslCertificate: support large serial numbers
We were calling an OpenSSL function that returned a long for the serial number; sometimes serial numbers are too big to fit into a long (up to 20 octets). In that case, do not convert the serial number to decimal, but just output the hexadecimal value. Reviewed-by: Zeno Albisser Task-number: QTBUG-9973
-rw-r--r--src/network/ssl/qsslcertificate.cpp23
-rw-r--r--tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem14
-rw-r--r--tests/auto/qsslcertificate/tst_qsslcertificate.cpp13
3 files changed, 46 insertions, 4 deletions
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index fd647e2..31c5ed1 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -259,13 +259,28 @@ QByteArray QSslCertificate::version() const
/*!
Returns the certificate's serial number string in decimal format.
+ In case the serial number cannot be converted to decimal format
+ (i.e. if it is bigger than 4294967295, which means it does not fit into 4 bytes),
+ its hexadecimal version is returned.
*/
QByteArray QSslCertificate::serialNumber() const
{
- if (d->serialNumberString.isEmpty() && d->x509)
- d->serialNumberString =
- QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->serialNumber)));
-
+ if (d->serialNumberString.isEmpty() && d->x509) {
+ ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber;
+ // if we cannot convert to a long, just output the hexadecimal number
+ if (serialNumber->length > 4) {
+ QByteArray hexString;
+ hexString.reserve(serialNumber->length * 3);
+ for (int a = 0; a < serialNumber->length; ++a) {
+ hexString += QByteArray::number(serialNumber->data[a], 16).rightJustified(2, '0');
+ hexString += ':';
+ }
+ hexString.chop(1);
+ d->serialNumberString = hexString;
+ } else {
+ d->serialNumberString = QByteArray::number(qlonglong(q_ASN1_INTEGER_get(serialNumber)));
+ }
+ }
return d->serialNumberString;
}
diff --git a/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem b/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem
new file mode 100644
index 0000000..ecb6c35
--- /dev/null
+++ b/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICGjCCAYMCFAECAwQFBgcICRCqu8zd7v8XGBkgMA0GCSqGSIb3DQEBBQUAMEwx
+CzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1
+cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMB4XDTEwMDYwMTE1MDI0MVoXDTEx
+MDYwMTE1MDI0MVowTDELMAkGA1UEBhMCR0IxEjAQBgNVBAgTCUJlcmtzaGlyZTEQ
+MA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkgQ29tcGFueSBMdGQwgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6e
+KHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93Cx
+GBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgB
+fWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtlScqSn4IHFLRiQYQdfOgsPi
+wdqD1MPZEniQE0Xp8McZ7kuYbGgdEqzeVgMHqitlzkNNtTz+2u37CbFNXDGCTy5D
+2JCgZxaAWNkh1w+4VB91HfMwEU0MqvAO7SB31FwbKNaB3gVnua++NL1cAkujyRny
+yR3PatYZCfESQ7oZgds=
+-----END CERTIFICATE-----
diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
index c76c11f..505b867 100644
--- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
+++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
@@ -109,6 +109,7 @@ private slots:
void task256066toPem();
void nulInCN();
void nulInSan();
+ void largeSerialNumber();
// ### add tests for certificate bundles (multiple certificates concatenated into a single
// structure); both PEM and DER formatted
#endif
@@ -786,6 +787,18 @@ void tst_QSslCertificate::nulInSan()
QCOMPARE(dnssan, QString::fromLatin1(realSAN, sizeof realSAN - 1));
}
+void tst_QSslCertificate::largeSerialNumber()
+{
+ QList<QSslCertificate> certList =
+ QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem");
+
+ QCOMPARE(certList.size(), 1);
+
+ const QSslCertificate &cert = certList.at(0);
+ QVERIFY(!cert.isNull());
+ QCOMPARE(cert.serialNumber(), QByteArray("01:02:03:04:05:06:07:08:09:10:aa:bb:cc:dd:ee:ff:17:18:19:20"));
+}
+
#endif // QT_NO_OPENSSL
QTEST_MAIN(tst_QSslCertificate)