/*! \internal Returns a DER key formatted as PEM. */ QByteArray QSslKeyPrivate::pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const { QByteArray pem(der.toBase64()); const int lineWidth = 64; // RFC 1421 const int newLines = pem.size() / lineWidth; const bool rem = pem.size() % lineWidth; // ### optimize for (int i = 0; i < newLines; ++i) pem.insert((i + 1) * lineWidth + i, '\n'); if (rem) pem.append('\n'); // ### QByteArray extra; if (!headers.isEmpty()) { QMap<QByteArray, QByteArray>::const_iterator it = headers.constEnd(); do { --it; extra += it.key() + ": " + it.value() + '\n'; } while (it != headers.constBegin()); extra += '\n'; } pem.prepend(pemHeader() + '\n' + extra); pem.append(pemFooter() + '\n'); return pem; }
/*! \internal Returns a PEM key formatted as DER. */ QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const { const QByteArray header = pemHeader(); const QByteArray footer = pemFooter(); QByteArray der(pem); const int headerIndex = der.indexOf(header); const int footerIndex = der.indexOf(footer); if (headerIndex == -1 || footerIndex == -1) return QByteArray(); der = der.mid(headerIndex + header.size(), footerIndex - (headerIndex + header.size())); if (der.contains("Proc-Type:")) { // taken from QHttpNetworkReplyPrivate::parseHeader const QByteArrayMatcher lf("\n"); const QByteArrayMatcher colon(":"); int i = 0; while (i < der.count()) { int j = colon.indexIn(der, i); // field-name if (j == -1) break; const QByteArray field = der.mid(i, j - i).trimmed(); j++; // any number of LWS is allowed before and after the value QByteArray value; do { i = lf.indexIn(der, j); if (i == -1) break; if (!value.isEmpty()) value += ' '; // check if we have CRLF or only LF bool hasCR = (i && der[i-1] == '\r'); int length = i -(hasCR ? 1: 0) - j; value += der.mid(j, length).trimmed(); j = ++i; } while (i < der.count() && (der.at(i) == ' ' || der.at(i) == '\t')); if (i == -1) break; // something is wrong headers->insert(field, value); } der = der.mid(i); } return QByteArray::fromBase64(der); // ignores newlines }
/*! \internal Returns a PEM key formatted as DER. */ QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem) const { const QByteArray header = pemHeader(); const QByteArray footer = pemFooter(); QByteArray der(pem); const int headerIndex = der.indexOf(header); const int footerIndex = der.indexOf(footer); if (headerIndex == -1 || footerIndex == -1) return QByteArray(); der = der.mid(headerIndex + header.size(), footerIndex - (headerIndex + header.size())); return QByteArray::fromBase64(der); // ignores newlines }
/*! \internal Returns a DER key formatted as PEM. */ QByteArray QSslKeyPrivate::pemFromDer(const QByteArray &der) const { QByteArray pem(der.toBase64()); const int lineWidth = 64; // RFC 1421 const int newLines = pem.size() / lineWidth; const bool rem = pem.size() % lineWidth; // ### optimize for (int i = 0; i < newLines; ++i) pem.insert((i + 1) * lineWidth + i, '\n'); if (rem) pem.append('\n'); // ### pem.prepend(pemHeader()); pem.append(pemFooter()); return pem; }