Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[auth] Convert PKCS8 to PKCS1 private keys (for macOS) #5401

Merged
merged 5 commits into from
Oct 26, 2017

Conversation

dakcarto
Copy link
Member

@dakcarto dakcarto commented Oct 18, 2017

Description

This addresses an issue I found during dev meeting in Essen (unreported until now).

Extracts the PrivateKey ASN.1 element of a DER-encoded PKCS#8 private key:

On some platforms, e.g. macOS, where the default SSL backend is not OpenSSL, a QSslKey can not be created using PKCS#8-formatted data. However, PKCS#8 private key ASN.1 structures contain the key data inside a wrapper describing the algorithm used, e.g. RSA, DSA, ECC etc. Extracted PrivateKey ASN.1 data can be used to create a compatible QSslKey, e.g. 'traditional' SSLeay RSA-specific PKCS#1.

By default OpenSSL 1.0.0+ returns private keys as PKCS#8, previously it was PKCS#1.

NOTE: This function requires 'libtasn1' development files and library, which is used to parse and extract the PrivateKey element from an ASN.1 PKCS#8 structure.

Also, adds more PEM- and DER-formatted client keys for testing.

Checklist

Reviewing is a process done by project maintainers, mostly on a volunteer basis. We try to keep the overhead as small as possible and appreciate if you help us to do so by completing the following items. Feel free to ask in a comment if you have troubles with any of them.

  • Commit messages are descriptive and explain the rationale for changes
  • Commits which fix bugs include fixes #11111 in the commit message next to the description
  • Commits which add new features are tagged with [FEATURE] in the commit message
  • Commits which change the UI or existing user workflows are tagged with [needs-docs] in the commit message and containt sufficient information in the commit message to be documented
  • I have read the QGIS Coding Standards and this PR complies with them
  • This PR passes all existing unit tests (test results will be reported by travis-ci after opening this PR)
  • New unit tests have been added for core changes
  • I have run the scripts/prepare-commit.sh script before each commit

See description of QgsAuthCertUtils::pkcs8PrivateKey.

This fix may be needed on other platforms (untested at this point),
because Qt5 QSslkey class *still* does not directly support creation
using non-PKCS1 PEM- or DER-encoded data, though QCA, whose qca-ossl
plugin is linked to OpenSSL, does support PKCS1 and PKCS8.
@dakcarto dakcarto requested a review from elpaso October 18, 2017 22:32
@dakcarto dakcarto changed the title Convert PKCS8 to PKCS1 private keys (for macOS) [auth] Convert PKCS8 to PKCS1 private keys (for macOS) Oct 18, 2017
Copy link
Contributor

@elpaso elpaso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I didn't check all the key manipulation code, I'd need to study for quite some time in order to understand what it does with those different PKCS formats.
BTW if you really need an in-depth review of the key manipulation code, please let me know and I'll schedule the task.

}
file.close();

return data;
}

QList<QSslCertificate> QgsAuthCertUtils::certsFromFile( const QString &certspath )
{
QList<QSslCertificate> certs;
bool pem = certspath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in scope with this PR, but here is one of the places were we should be more robust: if the file extension is not a reliable sign of the encoding, we should be trying both encoding before we give up, ignoring the file extension completely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it needs addressed, but it is a larger refactoring, across many auth classes. Note this work already has an internal Boundless JIRA ticket for exactly that auth API change/refactoring.

@@ -262,37 +273,249 @@ QStringList QgsAuthCertUtils::certKeyBundleToPem( const QString &certpath,
return QStringList() << certpem << keypem << algtype;
}

bool QgsAuthCertUtils::pemIsPkcs8( const QString &keyPemTxt )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment: can this function be used to detect PEM vs DER instead of the file extension ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't do encoding determination. It specifically has to work with PEM in order to simply text search to determine PKCS format (much more involved if using DER). I suppose the signature could be more descriptive, e.g. privateKeyPemIsPkcs8 (...).

@dakcarto
Copy link
Member Author

@elpaso thanks for the code review. However, I realize it is not so easy to functionally test, as it requires macOS and the libtasn1 extra library.

pkcs1 = QByteArray( oct_data, oct_len );

// !!! SENSITIVE DATA !!!
QgsDebugMsgLevel( QStringLiteral( "privateKey octet data as PEM: %1" ).arg( QString( pkcs1.toBase64() ) ), 9 );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elpaso, @m-kuhn, @nyalldawson, (and anyone else) thoughts on whether it is OK to leave this debug output active, but set the QgsDebugMsgLevel high, e.g. 9 here. Previously, I've left these kind of lines in the code, but commented out (with a warning not to leave uncommented). I can envision a circumstance where the env var QGIS_DEBUG might be manipulated somehow, thus exposing the credentials.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd hide it - " there's no reward in the risk" of exposing this to the log.

(+1million if anyone gets that reference)

@dakcarto dakcarto merged commit 3210f85 into qgis:master Oct 26, 2017
@dakcarto dakcarto deleted the pkcs8-to-pkcs1 branch October 26, 2017 18:42
@dakcarto
Copy link
Member Author

Merged as the latest indention error makes no sense. Previous commit CI passed. Most recent commit would cause no issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants