QgsPkiBundle *QgsAuthProviderPkiPkcs12::getPkiBundle( const QString &authcfg )
{
  QgsPkiBundle * bundle = 0;

  // check if it is cached
  if ( mPkiBundleCache.contains( authcfg ) )
  {
    bundle = mPkiBundleCache.value( authcfg );
    if ( bundle )
    {
      QgsDebugMsg( QString( "Retrieved PKI bundle for authcfg %1" ).arg( authcfg ) );
      return bundle;
    }
  }

  // else build PKI bundle
  QgsAuthConfigPkiPkcs12 config;

  if ( !QgsAuthManager::instance()->loadAuthenticationConfig( authcfg, config, true ) )
  {
    QgsDebugMsg( QString( "PKI bundle for authcfg %1: FAILED to retrieve config" ).arg( authcfg ) );
    return bundle;
  }

  // init client cert
  // Note: if this is not valid, no sense continuing
  QSslCertificate clientcert( QgsAuthProviderPkiPkcs12::certAsPem( config.bundlePath(), config.bundlePassphrase() ).toAscii() );
  if ( !clientcert.isValid() )
  {
    QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not valid" ).arg( authcfg ) );
    return bundle;
  }

  // init key
  QByteArray keydata( QgsAuthProviderPkiPkcs12::keyAsPem( config.bundlePath(), config.bundlePassphrase() ).toAscii() );

  if ( keydata.isNull() )
  {
    QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, no key data read" ).arg( authcfg ) );
    return bundle;
  }

  QSslKey clientkey( keydata,
                     QSsl::Rsa,
                     QSsl::Pem,
                     QSsl::PrivateKey,
                     !config.bundlePassphrase().isNull() ? config.bundlePassphrase().toUtf8() : QByteArray() );

  bundle = new QgsPkiBundle( config, clientcert, clientkey );

  // cache bundle
  putPkiBundle( authcfg, bundle );

  return bundle;

}
Beispiel #2
0
const QgsPkiBundle QgsPkiBundle::fromPemPaths( const QString &certPath,
    const QString &keyPath,
    const QString &keyPass,
    const QList<QSslCertificate> &caChain )
{
  QgsPkiBundle pkibundle;
  if ( !certPath.isEmpty() && !keyPath.isEmpty()
       && ( certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
            || certPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
       && ( keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
            || keyPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
       && QFile::exists( certPath ) && QFile::exists( keyPath )
     )
  {
    // client cert
    bool pem = certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
    QSslCertificate clientcert( fileData_( certPath, pem ), pem ? QSsl::Pem : QSsl::Der );
    pkibundle.setClientCert( clientcert );

    // client key
    bool pem_key = keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
    QByteArray keydata( fileData_( keyPath, pem_key ) );

    QSslKey clientkey;
    clientkey = QSslKey( keydata,
                         QSsl::Rsa,
                         pem_key ? QSsl::Pem : QSsl::Der,
                         QSsl::PrivateKey,
                         !keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
    if ( clientkey.isNull() )
    {
      // try DSA algorithm, since Qt can't seem to determine it otherwise
      clientkey = QSslKey( keydata,
                           QSsl::Dsa,
                           pem_key ? QSsl::Pem : QSsl::Der,
                           QSsl::PrivateKey,
                           !keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
    }
    pkibundle.setClientKey( clientkey );
    if ( !caChain.isEmpty() )
    {
      pkibundle.setCaChain( caChain );
    }
  }
  return pkibundle;
}
// static
const QByteArray QgsAuthProviderPkiPaths::keyAsPem( const QString &keypath,
    const QString &keypass,
    QString *algtype,
    bool reencrypt )
{
  bool pem = keypath.endsWith( ".pem", Qt::CaseInsensitive );
  QByteArray keydata( fileData_( keypath, pem ) );

  QSslKey clientkey;
  clientkey = QSslKey( keydata,
                       QSsl::Rsa,
                       pem ? QSsl::Pem : QSsl::Der,
                       QSsl::PrivateKey,
                       !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
  if ( clientkey.isNull() )
  {
    // try DSA algorithm, since Qt can't seem to determine it otherwise
    clientkey = QSslKey( keydata,
                         QSsl::Dsa,
                         pem ? QSsl::Pem : QSsl::Der,
                         QSsl::PrivateKey,
                         !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
    if ( clientkey.isNull() )
    {
      return QByteArray();
    }
    if ( algtype )
      *algtype = "dsa";
  }
  else
  {
    if ( algtype )
      *algtype = "rsa";
  }

  // reapply passphrase if protection is requested and passphrase exists
  return ( clientkey.toPem( reencrypt && !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() ) );
}
static int qcom_km_import_keypair(const keymaster_device_t* dev,
        const uint8_t* key, const size_t key_length,
        uint8_t** keyBlob, size_t* keyBlobLength)
{
    if (dev->context == NULL) {
        ALOGE("qcom_km_import_keypair: Context  == NULL");
        return -1;
    }

    if (key == NULL) {
        ALOGE("Input key == NULL");
        return -1;
    } else if (keyBlob == NULL || keyBlobLength == NULL) {
        ALOGE("Output key blob or length == NULL");
        return -1;
    }

    struct QSEECom_ion_fd_info  ion_fd_info;
    struct qcom_km_ion_info_t ihandle;
    int ret = 0;

    ihandle.ion_fd = 0;
    ihandle.ion_alloc_handle.handle = NULL;
    if (qcom_km_ION_memalloc(&ihandle, QSEECOM_ALIGN(key_length)) < 0) {
        ALOGE("ION allocation  failed");
        return -1;
    }
    memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));

    /* Populate the send data structure */
    ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
    ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t);


    struct QSEECom_handle *handle = NULL;
    keymaster_import_keypair_cmd_t *send_cmd = NULL;
    keymaster_import_keypair_resp_t  *resp = NULL;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    send_cmd = (keymaster_import_keypair_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_import_keypair_resp_t *)(handle->ion_sbuffer +
                                        QSEECOM_ALIGN(sizeof(keymaster_import_keypair_cmd_t)));
    send_cmd->cmd_id = KEYMASTER_IMPORT_KEYPAIR;
    send_cmd->pkcs8_key = (uint32_t)ihandle.ion_sbuffer;

    memcpy((unsigned char *)ihandle.ion_sbuffer, key, key_length);

    send_cmd->pkcs8_key_len = key_length;
    resp->status = KEYMASTER_FAILURE;
    resp->key_blob_len =  sizeof(qcom_km_key_blob_t);

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Import key command failed (unable to enable clks) ret =%d", ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    }
    ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
                               QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Import key command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Import key command failed resp->status = %d ret =%d", resp->status, ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    } else {
        UniquePtr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
        if (keydata.get() == NULL) {
            ALOGE("could not allocate memory for key blob");
            return -1;
        }
        unsigned char* p = keydata.get();
        memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
        *keyBlob = keydata.release();
        *keyBlobLength = resp->key_blob_len;

    }
    qcom_km_ion_dealloc(&ihandle);
    return 0;
}
static int qcom_km_generate_keypair(const keymaster_device_t* dev,
        const keymaster_keypair_t key_type, const void* key_params,
        uint8_t** keyBlob, size_t* keyBlobLength) {

    if (dev->context == NULL) {
        ALOGE("qcom_km_generate_keypair: Context == NULL");
        return -1;
    }

    if (key_type != TYPE_RSA) {
        ALOGE("Unsupported key type %d", key_type);
        return -1;
    } else if (key_params == NULL) {
        ALOGE("key_params == null");
        return -1;
    }
    if (keyBlob == NULL || keyBlobLength == NULL) {
        ALOGE("output key blob or length == NULL");
        return -1;
    }
    keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;

    keymaster_gen_keypair_cmd_t *send_cmd = NULL;
    keymaster_gen_keypair_resp_t  *resp = NULL;
    struct QSEECom_handle *handle = NULL;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
    int ret = 0;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    send_cmd = (keymaster_gen_keypair_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_gen_keypair_resp_t *)(handle->ion_sbuffer +
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)));
    send_cmd->cmd_id = KEYMASTER_GENERATE_KEYPAIR;
    send_cmd->key_type = key_type;
    send_cmd->rsa_params.modulus_size = rsa_params->modulus_size;
    send_cmd->rsa_params.public_exponent = rsa_params->public_exponent;
    resp->status = KEYMASTER_FAILURE;
    resp->key_blob_len =  sizeof(qcom_km_key_blob_t);

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Generate key command failed (unable to enable clks) ret =%d", ret);
        return -1;
    }

    ret = (*km_handle->QSEECom_send_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)), resp,
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_resp_t)));

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Import key command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Generate key command failed resp->status = %d ret =%d", resp->status, ret);
        return -1;
    } else {
        UniquePtr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
        if (keydata.get() == NULL) {
            ALOGE("could not allocate memory for key blob");
            return -1;
        }
        unsigned char* p = keydata.get();
        memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
        *keyBlob = keydata.release();
        *keyBlobLength = resp->key_blob_len;
    }
    return 0;
}