LCOV - code coverage report
Current view: top level - core/auth - qgsauthcrypto.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 74 0.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsauthcrypto.cpp
       3                 :            :     ---------------------
       4                 :            :     begin                : October 5, 2014
       5                 :            :     copyright            : (C) 2014 by Boundless Spatial, Inc. USA
       6                 :            :     author               : Larry Shaffer
       7                 :            :     email                : lshaffer at boundlessgeo dot com
       8                 :            :  ***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : 
      17                 :            : #include "qgsauthcrypto.h"
      18                 :            : 
      19                 :            : #include <QObject>
      20                 :            : #include <QtCrypto>
      21                 :            : 
      22                 :            : // defines culled from MeePasswords (GPL2)
      23                 :            : // https://github.com/ruedigergad/meepasswords/blob/master/entrystorage.h
      24                 :            : #define CIPHER_SIGNATURE "aes256-cbc-pkcs7"
      25                 :            : #define CIPHER_TYPE "aes256"
      26                 :            : #define CIPHER_MODE QCA::Cipher::CBC
      27                 :            : #define CIPHER_PADDING QCA::Cipher::PKCS7
      28                 :            : #define CIPHER_IV_LENGTH 32
      29                 :            : #define CIPHER_PROVIDER "qca-ossl"
      30                 :            : #define PASSWORD_HASH_ALGORITHM "sha256"
      31                 :            : #define KEY_GEN_ITERATIONS 10000
      32                 :            : #define KEY_GEN_LENGTH 16
      33                 :            : #define KEY_GEN_IV_LENGTH 16
      34                 :            : 
      35                 :          0 : bool QgsAuthCrypto::isDisabled()
      36                 :            : {
      37                 :          0 :   if ( !QCA::isSupported( CIPHER_SIGNATURE, CIPHER_PROVIDER ) )
      38                 :            :   {
      39                 :          0 :     qDebug( "Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing" );
      40                 :          0 :     return true;
      41                 :            :   }
      42                 :          0 :   return false;
      43                 :          0 : }
      44                 :            : 
      45                 :          0 : const QString QgsAuthCrypto::encrypt( const QString &pass, const QString &cipheriv, const QString &text )
      46                 :            : {
      47                 :          0 :   if ( QgsAuthCrypto::isDisabled() )
      48                 :          0 :     return QString();
      49                 :            : 
      50                 :          0 :   return encryptdecrypt( pass, cipheriv, text, true );
      51                 :          0 : }
      52                 :            : 
      53                 :          0 : const QString QgsAuthCrypto::decrypt( const QString &pass, const QString &cipheriv, const QString &text )
      54                 :            : {
      55                 :          0 :   if ( QgsAuthCrypto::isDisabled() )
      56                 :          0 :     return QString();
      57                 :            : 
      58                 :          0 :   return encryptdecrypt( pass, cipheriv, text, false );
      59                 :          0 : }
      60                 :            : 
      61                 :          0 : static QCA::SymmetricKey passwordKey_( const QString &pass, const QCA::InitializationVector &salt )
      62                 :            : {
      63                 :          0 :   QCA::SecureArray passarray( QByteArray( pass.toUtf8().constData() ) );
      64                 :          0 :   QCA::SecureArray passhash( QCA::Hash( PASSWORD_HASH_ALGORITHM ).hash( passarray ) );
      65                 :          0 :   return QCA::PBKDF2().makeKey( passhash, salt, KEY_GEN_LENGTH, KEY_GEN_ITERATIONS );
      66                 :          0 : }
      67                 :            : 
      68                 :          0 : void QgsAuthCrypto::passwordKeyHash( const QString &pass, QString *salt, QString *hash, QString *cipheriv )
      69                 :            : {
      70                 :          0 :   if ( QgsAuthCrypto::isDisabled() )
      71                 :          0 :     return;
      72                 :            : 
      73                 :          0 :   QCA::InitializationVector saltiv = QCA::InitializationVector( KEY_GEN_IV_LENGTH );
      74                 :          0 :   QCA::SymmetricKey key = passwordKey_( pass, saltiv );
      75                 :            : 
      76                 :          0 :   if ( !key.isEmpty() )
      77                 :            :   {
      78                 :          0 :     *salt = QCA::arrayToHex( saltiv.toByteArray() );
      79                 :          0 :     qDebug( "salt hex: %s", qPrintable( *salt ) );
      80                 :            : 
      81                 :          0 :     *hash = QCA::arrayToHex( key.toByteArray() );
      82                 :          0 :     qDebug( "hash hex: %s", qPrintable( *hash ) );
      83                 :            : 
      84                 :          0 :     if ( cipheriv )
      85                 :            :     {
      86                 :          0 :       *cipheriv = QCA::arrayToHex( QCA::InitializationVector( CIPHER_IV_LENGTH ).toByteArray() );
      87                 :          0 :       qDebug( "cipheriv hex: %s", qPrintable( *cipheriv ) );
      88                 :          0 :     }
      89                 :          0 :   }
      90                 :          0 : }
      91                 :            : 
      92                 :          0 : bool QgsAuthCrypto::verifyPasswordKeyHash( const QString &pass,
      93                 :            :     const QString &salt,
      94                 :            :     const QString &hash,
      95                 :            :     QString *hashderived )
      96                 :            : {
      97                 :          0 :   if ( QgsAuthCrypto::isDisabled() )
      98                 :          0 :     return false;
      99                 :            : 
     100                 :          0 :   QCA::InitializationVector saltiv( QCA::hexToArray( salt ) );
     101                 :          0 :   QString derived( QCA::arrayToHex( passwordKey_( pass, saltiv ).toByteArray() ) );
     102                 :            : 
     103                 :          0 :   if ( hashderived )
     104                 :            :   {
     105                 :          0 :     *hashderived = derived;
     106                 :          0 :   }
     107                 :            : 
     108                 :          0 :   return hash == derived;
     109                 :          0 : }
     110                 :            : 
     111                 :          0 : QString QgsAuthCrypto::encryptdecrypt( const QString &passstr,
     112                 :            :                                        const QString &cipheriv,
     113                 :            :                                        const QString &textstr,
     114                 :            :                                        bool encrypt )
     115                 :            : {
     116                 :          0 :   QString outtxt = QString();
     117                 :          0 :   if ( QgsAuthCrypto::isDisabled() )
     118                 :          0 :     return outtxt;
     119                 :            : 
     120                 :          0 :   QCA::InitializationVector iv( QCA::hexToArray( cipheriv ) );
     121                 :            : 
     122                 :          0 :   QCA::SymmetricKey key( QCA::SecureArray( QByteArray( passstr.toUtf8().constData() ) ) );
     123                 :            : 
     124                 :          0 :   if ( encrypt )
     125                 :            :   {
     126                 :          0 :     QCA::Cipher cipher = QCA::Cipher( CIPHER_TYPE, CIPHER_MODE, CIPHER_PADDING,
     127                 :            :                                       QCA::Encode, key, iv,
     128                 :          0 :                                       CIPHER_PROVIDER );
     129                 :            : 
     130                 :          0 :     QCA::SecureArray securedata( textstr.toUtf8() );
     131                 :          0 :     QCA::SecureArray encrypteddata( cipher.process( securedata ) );
     132                 :          0 :     if ( !cipher.ok() )
     133                 :            :     {
     134                 :          0 :       qDebug( "Encryption failed!" );
     135                 :          0 :       return outtxt;
     136                 :            :     }
     137                 :          0 :     outtxt = QCA::arrayToHex( encrypteddata.toByteArray() );
     138                 :            :     // qDebug( "Encrypted hex: %s", qPrintable( outtxt ) );
     139                 :          0 :   }
     140                 :            :   else
     141                 :            :   {
     142                 :          0 :     QCA::Cipher cipher = QCA::Cipher( CIPHER_TYPE, CIPHER_MODE, CIPHER_PADDING,
     143                 :            :                                       QCA::Decode, key, iv,
     144                 :          0 :                                       CIPHER_PROVIDER );
     145                 :            : 
     146                 :          0 :     QCA::SecureArray ciphertext( QCA::hexToArray( textstr ) );
     147                 :          0 :     QCA::SecureArray decrypteddata( cipher.process( ciphertext ) );
     148                 :          0 :     if ( !cipher.ok() )
     149                 :            :     {
     150                 :          0 :       qDebug( "Decryption failed!" );
     151                 :          0 :       return outtxt;
     152                 :            :     }
     153                 :            : 
     154                 :          0 :     outtxt = QString( decrypteddata.toByteArray() );
     155                 :            :     // qDebug( "Decrypted text %s", qPrintable( outtxt ) ); // DO NOT LEAVE THIS LINE UNCOMMENTED
     156                 :          0 :   }
     157                 :            : 
     158                 :          0 :   return outtxt;
     159                 :          0 : }

Generated by: LCOV version 1.14