X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fcertificate.cc;h=fbe3a80d2c2c9b6667f2085a704749d015df82f8;hb=refs%2Fheads%2F1.0-templates;hp=72c53610c54bef9f8b5a78b189c5e272186d2acd;hpb=89d891bfc20ce3f7929a72ce1c334fa4f00b2139;p=libdcp.git diff --git a/src/certificate.cc b/src/certificate.cc index 72c53610..fbe3a80d 100644 --- a/src/certificate.cc +++ b/src/certificate.cc @@ -1,32 +1,46 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2016 Carl Hetherington - This program is free software; you can redistribute it and/or modify + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + libdcp 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 General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + along with libdcp. If not, see . + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. */ /** @file src/certificate.cc * @brief Certificate class. */ -#include "KM_util.h" #include "certificate.h" #include "compose.hpp" #include "exceptions.h" #include "util.h" #include "dcp_assert.h" +#include #include #include #include @@ -34,13 +48,13 @@ #include #include #include +#include #include using std::list; using std::string; using std::ostream; using std::min; -using std::stringstream; using namespace dcp; static string const begin_certificate = "-----BEGIN CERTIFICATE-----"; @@ -61,7 +75,10 @@ Certificate::Certificate (string cert) : _certificate (0) , _public_key (0) { - read_string (cert); + string const s = read_string (cert); + if (!s.empty ()) { + throw MiscError ("unexpected data after certificate"); + } } /** Copy constructor. @@ -71,45 +88,72 @@ Certificate::Certificate (Certificate const & other) : _certificate (0) , _public_key (0) { - read_string (other.certificate (true)); + if (other._certificate) { + read_string (other.certificate (true)); + } } /** Read a certificate from a string. * @param cert String to read. + * @return remaining part of the input string after the certificate which was read. */ -void +string Certificate::read_string (string cert) { /* Reformat cert so that it has line breaks every 64 characters. See http://comments.gmane.org/gmane.comp.encryption.openssl.user/55593 */ - stringstream s (cert); + list lines; string line; + for (size_t i = 0; i < cert.length(); ++i) { + line += cert[i]; + if (cert[i] == '\r' || cert[i] == '\n') { + boost::algorithm::trim (line); + lines.push_back (line); + line = ""; + } + } + + if (!line.empty()) { + boost::algorithm::trim (line); + lines.push_back (line); + } + + list::iterator i = lines.begin (); + /* BEGIN */ - getline (s, line); - boost::algorithm::trim (line); - if (line != begin_certificate) { + while (i != lines.end() && *i != begin_certificate) { + ++i; + } + + if (i == lines.end()) { throw MiscError ("missing BEGIN line in certificate"); } + /* Skip over the BEGIN line */ + ++i; + /* The base64 data */ bool got_end = false; string base64 = ""; - while (getline (s, line)) { - boost::algorithm::trim (line); - if (line == end_certificate) { + while (i != lines.end()) { + if (*i == end_certificate) { got_end = true; break; } - base64 += line; + base64 += *i; + ++i; } if (!got_end) { throw MiscError ("missing END line in certificate"); } + /* Skip over the END line */ + ++i; + /* Make up the fixed version */ string fixed = begin_certificate + "\n"; @@ -132,6 +176,17 @@ Certificate::read_string (string cert) } BIO_free (bio); + + string extra; + + while (i != lines.end()) { + if (!i->empty()) { + extra += *i + "\n"; + } + ++i; + } + + return extra; } /** Destructor */