LCOV - code coverage report
Current view: top level - core - awssignaturev1.cpp (source / functions) Hit Total Coverage
Test: libqtaws 0.1.0 Lines: 21 21 100.0 %
Date: 2015-06-16 07:50:35 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :     Copyright 2013-2015 Paul Colby
       3             : 
       4             :     This file is part of libqtaws.
       5             : 
       6             :     Libqtaws is free software: you can redistribute it and/or modify
       7             :     it under the terms of the GNU Lesser General Public License as published by
       8             :     the Free Software Foundation, either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     Libqtaws is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU Lesser General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU Lesser General Public License
      17             :     along with libqtaws.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "awssignaturev1.h"
      21             : #include "awssignaturev1_p.h"
      22             : 
      23             : #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
      24             : #include "qmessageauthenticationcode.h"
      25             : #else
      26             : #include <QMessageAuthenticationCode>
      27             : #endif
      28             : 
      29             : #include <QCryptographicHash>
      30             : #include <QDebug>
      31             : #include <QNetworkRequest>
      32             : #include <QUrl>
      33             : 
      34             : QTAWS_BEGIN_NAMESPACE
      35             : 
      36             : /**
      37             :  * @class  AwsSignatureV1
      38             :  *
      39             :  * @brief  Implements AWS Signature Version 1 \ref deprecated "(deprecated by Amazon)"
      40             :  *
      41             :  * @deprecated  Amazon has officially deprecated signature Version 1 in favor of later,
      42             :  *              more secure signatures, such as AwsSignatureV2 and AwsSignatureV4.
      43             :  *
      44             :  * As version 1 signatures are rightly regarded as *insecure*, this class will refuse to sign
      45             :  * requests that use insecure transports such as HTTP instead of HTTPS. However, insecure
      46             :  * signatures can be enabled (why would you want to?) by defining `QTAWS_ALLOW_INSECURE_SIGNATURES`
      47             :  * when compiling this library.
      48             :  *
      49             :  * @see  http://s3.amazonaws.com/awsdocs/SQS/20070501/sqs-dg-20070501.pdf
      50             :  * @see  http://lmgtfy.com/?q=aws+signature+version+1+is+insecure
      51             :  */
      52             : 
      53             : /**
      54             :  * @brief  Constructs a new AwsSignatureV1 object.
      55             :  *
      56             :  * Use instances of this object to provide Version 1 signatures for AWS services.
      57             :  */
      58           8 : AwsSignatureV1::AwsSignatureV1() : AwsSignatureV0(new AwsSignatureV1Private(this))
      59             : {
      60             : 
      61           8 : }
      62             : 
      63           4 : int AwsSignatureV1::version() const
      64             : {
      65           4 :     return 1;
      66             : }
      67             : 
      68             : /**
      69             :  * @internal
      70             :  *
      71             :  * @class  AwsSignatureV1Private
      72             :  *
      73             :  * @brief  Private implementation for AwsSignatureV1.
      74             :  *
      75             :  * @warning  This is an internal private implementation class, and as such external should
      76             :  *           code should **not** depend directly on anything contained within this class.
      77             :  *
      78             :  * @see    http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
      79             :  */
      80             : 
      81             : /**
      82             :  * @internal
      83             :  *
      84             :  * @brief  Constructs a new AwsSignatureV1Private object.
      85             :  *
      86             :  * @param  q  Pointer to this object's public AwsSignatureV1 instance.
      87             :  */
      88           8 : AwsSignatureV1Private::AwsSignatureV1Private(AwsSignatureV1 * const q) : AwsSignatureV0Private(q)
      89             : {
      90             : 
      91           8 : }
      92             : 
      93             : /**
      94             :  * @internal
      95             :  *
      96             :  * @brief  Create an AWS Signature version 1 canonical query.
      97             :  *
      98             :  * This function returns a string containing all non-empty query parameters in
      99             :  * sorted order (case-insensitive), with no separators at all.
     100             :  *
     101             :  * For example, for the following SQS query string:
     102             :  *
     103             :  *     ?Action=CreateQueue&QueueName=queue2&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&SignatureVersion=1&Expires=2007-01-12T12:00:00Z&Version=2006-04-01
     104             :  *
     105             :  * this function will return the following canonical form:
     106             :  *
     107             :  *     ActionCreateQueueAWSAccessKeyIdAKIAIOSFODNN7EXAMPLEExpires2007-01-12T12:00:00ZQueueNamequeue2SignatureVersion1Version2006-04-01
     108             :  *
     109             :  * This function is very similar to AwsAbstractSignature::canonicalQuery(), except
     110             :  * that:
     111             :  *   1. this function sorts case-insensitively, whereas AwsAbstractSignature::canonicalQuery()
     112             :  *      use a byte sort (ie is case sensitive); and
     113             :  *   2. this function excludes parameters with empty values, where
     114             :  *      AwsAbstractSignature::canonicalQuery() includes all query parameters, regardless
     115             :  *      of content; and
     116             :  *   3. this function does not use any separators in the generated string, whereas
     117             :  *      AwsAbstractSignature::canonicalQuery() uses `&` and `=` separators just as
     118             :  *      you would expect to see them in a typical query string; and
     119             :  *   4. this function does not perform any URL encoding of the query parameters,
     120             :  *      whereas AwsAbstractSignature::canonicalQuery() URL encodes both parameter
     121             :  *      keys and values.
     122             :  *
     123             :  * The AwsAbstractSignature::canonicalQuery() function is used by the later signature
     124             :  * algorithms, such as AwsSignatureV2 and AwsSignatureV4, as required by Amazon. Instead
     125             :  * this function is specific to version 1 signatures.
     126             :  *
     127             :  * @param  query  Query to encode the HTTP query string from.
     128             :  *
     129             :  * @return An AWS Signature canonical query string.
     130             :  *
     131             :  * @see    http://docs.aws.amazon.com/AmazonDevPay/latest/DevPayDeveloperGuide/LSAPI_Auth_REST.html#CalculatingHMACSignature
     132             :  */
     133           5 : QByteArray AwsSignatureV1Private::canonicalQuery(const QUrlQuery &query) const
     134             : {
     135           5 :     QList<QStringPair> list = query.queryItems(QUrl::FullyDecoded);
     136           5 :     qSort(list.begin(), list.end(), AwsSignatureV1Private::caseInsensitiveLessThan);
     137          10 :     QString result;
     138          35 :     foreach (const QStringPair &pair, list) {
     139          30 :         if (!pair.second.isEmpty()) {
     140          30 :             result += pair.first + pair.second;
     141             :         }
     142           5 :     }
     143          10 :     return result.toUtf8();
     144             : }
     145             : 
     146             : /**
     147             :  * @internal
     148             :  *
     149             :  * @brief  Is a key-value pair less than another key-value pair?
     150             :  *
     151             :  * This static function is used by the canonicalQuery function to sort query string
     152             :  * parameters in case-insensitive order, via Qt's qSort function.
     153             :  *
     154             :  * @param  pair1  The first key-value (query string parameter) pair.
     155             :  * @param  pair2  The second key-value (query string parameter) pair.
     156             :  *
     157             :  * @returns `true` if \a pair1 is less than \a pair2.
     158             :  */
     159          96 : bool AwsSignatureV1Private::caseInsensitiveLessThan(const QStringPair &pair1, const QStringPair &pair2)
     160             : {
     161          96 :     if (pair1.first.toLower() < pair2.first.toLower())
     162          27 :         return true;
     163          69 :     if (pair1.first.toLower() > pair2.first.toLower())
     164          63 :         return false;
     165           6 :     return (pair1.second.toLower() < pair2.second.toLower());
     166             : }
     167             : 
     168             : QTAWS_END_NAMESPACE

Generated by: LCOV version 1.11