/* * Copyright (C) 2005 Justin Karneges * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * */ /* mozilla certdata converter. adapted from the debian ruby script */ #include #include #include #include #include QStringList splitWithQuotes(const QString &in, char c); int main(int argc, char **argv) { QCA::Initializer qcaInit; QCoreApplication app(argc, argv); if (argc < 3) { printf("usage: mozcerts [certdata.txt] [outfile.pem]\n"); return 0; } QFile infile(QString::fromLocal8Bit(argv[1])); if (!infile.open(QFile::ReadOnly)) { fprintf(stderr, "Error opening input file\n"); return 1; } QFile outfile(QString::fromLocal8Bit(argv[2])); if (!outfile.open(QFile::WriteOnly | QFile::Truncate)) { fprintf(stderr, "Error opening output file\n"); return 1; } int count = 0; QString name; QTextStream ts(&infile); while (!ts.atEnd()) { QString line = ts.readLine(); if (line.startsWith(QLatin1Char('#'))) continue; line = line.trimmed(); if (line.isEmpty()) continue; if (line.startsWith(QLatin1String("CKA_LABEL"))) { const QStringList list = splitWithQuotes(line, ' '); if (list.count() != 3) continue; name = list[2]; // make an output filename based on the name // outname = name.replace(QRegExp("\\/"), "_") // .replace(QRegExp("\\s+"), "_") // .replace(QRegExp("[()]"), "=") // .replace(QRegExp(","), "_") + ".pem"; continue; } else if (line == QLatin1String("CKA_VALUE MULTILINE_OCTAL")) { QByteArray buf; while (!ts.atEnd()) { line = ts.readLine().trimmed(); if (line == QLatin1String("END")) break; static const QRegularExpression rx(QStringLiteral("\\\\([0-3][0-7][0-7])")); int pos = 0; QRegularExpressionMatch match = rx.match(line, pos); while (match.hasMatch()) { QString str = match.captured(1); uchar c = str.toInt(nullptr, 8); buf.append(c); pos += match.capturedLength(); match = rx.match(line, pos); } } printf(">> [%s], %d bytes\n", qPrintable(name), int(buf.size())); QTextStream ts(&outfile); ts << "-----BEGIN CERTIFICATE-----" << '\n'; QCA::Base64 enc; enc.setLineBreaksEnabled(true); enc.setLineBreaksColumn(64); ts << enc.arrayToString(buf) << '\n'; ts << "-----END CERTIFICATE-----" << '\n'; ++count; } } printf("Wrote %d certs to [%s]\n", count, argv[2]); return 0; } int find_notchar(const QString &str, char c, int offset) { for (int n = offset; n < str.length(); ++n) { if (str[n] != QLatin1Char(c)) return n; } return -1; } QStringList splitWithQuotes(const QString &in, char c) { QStringList result; int at = 0; if (in[at] == QLatin1Char(c)) at = find_notchar(in, c, at); while (at != -1) { bool quote = false; int end; QString str; if (in[at] == QLatin1Char('\"')) { quote = true; ++at; end = in.indexOf(QLatin1Char('\"'), at); if (end == -1) break; } else end = in.indexOf(QLatin1Char(c), at); if (end != -1) str = in.mid(at, end - at); else str = in.mid(at); if (!str.isEmpty()) result += str; if (quote) end = in.indexOf(QLatin1Char(c), end); if (end != -1) at = find_notchar(in, c, end); else at = -1; } return result; }