File indexing completed on 2024-05-05 04:45:24
0001 /* 0002 * Copyright (C) 2005 Justin Karneges <justin@affinix.com> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 0017 * 0018 */ 0019 0020 /* mozilla certdata converter. adapted from the debian ruby script */ 0021 0022 #include <QtCrypto> 0023 0024 #include <QCoreApplication> 0025 #include <QFile> 0026 #include <QRegularExpression> 0027 #include <QTextStream> 0028 0029 QStringList splitWithQuotes(const QString &in, char c); 0030 0031 int main(int argc, char **argv) 0032 { 0033 QCA::Initializer qcaInit; 0034 QCoreApplication app(argc, argv); 0035 0036 if (argc < 3) { 0037 printf("usage: mozcerts [certdata.txt] [outfile.pem]\n"); 0038 return 0; 0039 } 0040 0041 QFile infile(QString::fromLocal8Bit(argv[1])); 0042 if (!infile.open(QFile::ReadOnly)) { 0043 fprintf(stderr, "Error opening input file\n"); 0044 return 1; 0045 } 0046 0047 QFile outfile(QString::fromLocal8Bit(argv[2])); 0048 if (!outfile.open(QFile::WriteOnly | QFile::Truncate)) { 0049 fprintf(stderr, "Error opening output file\n"); 0050 return 1; 0051 } 0052 0053 int count = 0; 0054 QString name; 0055 QTextStream ts(&infile); 0056 while (!ts.atEnd()) { 0057 QString line = ts.readLine(); 0058 if (line.startsWith(QLatin1Char('#'))) 0059 continue; 0060 line = line.trimmed(); 0061 if (line.isEmpty()) 0062 continue; 0063 0064 if (line.startsWith(QLatin1String("CKA_LABEL"))) { 0065 const QStringList list = splitWithQuotes(line, ' '); 0066 if (list.count() != 3) 0067 continue; 0068 0069 name = list[2]; 0070 // make an output filename based on the name 0071 // outname = name.replace(QRegExp("\\/"), "_") 0072 // .replace(QRegExp("\\s+"), "_") 0073 // .replace(QRegExp("[()]"), "=") 0074 // .replace(QRegExp(","), "_") + ".pem"; 0075 continue; 0076 } else if (line == QLatin1String("CKA_VALUE MULTILINE_OCTAL")) { 0077 QByteArray buf; 0078 while (!ts.atEnd()) { 0079 line = ts.readLine().trimmed(); 0080 if (line == QLatin1String("END")) 0081 break; 0082 static const QRegularExpression rx(QStringLiteral("\\\\([0-3][0-7][0-7])")); 0083 int pos = 0; 0084 QRegularExpressionMatch match = rx.match(line, pos); 0085 while (match.hasMatch()) { 0086 QString str = match.captured(1); 0087 uchar c = str.toInt(nullptr, 8); 0088 buf.append(c); 0089 pos += match.capturedLength(); 0090 match = rx.match(line, pos); 0091 } 0092 } 0093 0094 printf(">> [%s], %d bytes\n", qPrintable(name), int(buf.size())); 0095 0096 QTextStream ts(&outfile); 0097 ts << "-----BEGIN CERTIFICATE-----" << '\n'; 0098 QCA::Base64 enc; 0099 enc.setLineBreaksEnabled(true); 0100 enc.setLineBreaksColumn(64); 0101 ts << enc.arrayToString(buf) << '\n'; 0102 ts << "-----END CERTIFICATE-----" << '\n'; 0103 0104 ++count; 0105 } 0106 } 0107 printf("Wrote %d certs to [%s]\n", count, argv[2]); 0108 0109 return 0; 0110 } 0111 0112 int find_notchar(const QString &str, char c, int offset) 0113 { 0114 for (int n = offset; n < str.length(); ++n) { 0115 if (str[n] != QLatin1Char(c)) 0116 return n; 0117 } 0118 return -1; 0119 } 0120 0121 QStringList splitWithQuotes(const QString &in, char c) 0122 { 0123 QStringList result; 0124 int at = 0; 0125 if (in[at] == QLatin1Char(c)) 0126 at = find_notchar(in, c, at); 0127 while (at != -1) { 0128 bool quote = false; 0129 int end; 0130 QString str; 0131 if (in[at] == QLatin1Char('\"')) { 0132 quote = true; 0133 ++at; 0134 end = in.indexOf(QLatin1Char('\"'), at); 0135 if (end == -1) 0136 break; 0137 } else 0138 end = in.indexOf(QLatin1Char(c), at); 0139 0140 if (end != -1) 0141 str = in.mid(at, end - at); 0142 else 0143 str = in.mid(at); 0144 0145 if (!str.isEmpty()) 0146 result += str; 0147 0148 if (quote) 0149 end = in.indexOf(QLatin1Char(c), end); 0150 0151 if (end != -1) 0152 at = find_notchar(in, c, end); 0153 else 0154 at = -1; 0155 } 0156 return result; 0157 }