noloader / cryptopp-pem Goto Github PK
View Code? Open in Web Editor NEWPEM parsing of keys and parameters for Crypto++ project
PEM parsing of keys and parameters for Crypto++ project
In file x509cert.cpp on both lines 1425 and 1435 the code doesn't compile since the constructor of an ed25519::Verifier object cannot implicitly convert an X509PublicKey key.
The verifiers for existing encryption algorithms (e.g. ECDSA<ECP, SHA512>, RSASS<PSS, SHA256>, etc.) all provide a constructor (inherited from PK_FinalTemplate), accepting a const CryptoMaterial& key (which is a base class of type X509PublicKey).
I had resolved
The following line looks to be wrong and causes a problem when trying to use encrypted RSA pem files.
std::transform(t2.begin(), t2.end(), stdext::make_checked_array_iterator(**t1**.begin(), t1.size()), ByteToLower());
I believe it should be
std::transform(t2.begin(), t2.end(), stdext::make_checked_array_iterator(t2.begin(), t1.size()), ByteToLower());
When I use the following code to read an EC public key from a certificate that explicitly contains the EC parameters, the program fails to work as expected:
#include "cryptlib.h"
#include "x509cert.h"
#include "filters.h"
#include "sha.h"
#include "hex.h"
#include "pem.h"
#include "files.h"
#include <iostream>
#include <string>
extern const std::string pemCertificate;
int main(int argc, char* argv[])
{
using namespace CryptoPP;
StringSource ss(pemCertificate, true);
X509Certificate cert;
PEM_Load(ss, cert);
const X509PublicKey& publicKey = cert.GetSubjectPublicKey(); // fail
}
const std::string pemCertificate =
"-----BEGIN CERTIFICATE-----\r\n"
"MIICcjCCAhegAwIBAgIUC8OM0gRX41iXU2vLJbGmRjDMzTMwCgYIKoZIzj0EAwIw\r\n"
"FDESMBAGA1UEAwwJTUFMRk9STUVEMB4XDTI0MDIyNzA1MTU0NVoXDTI1MDIyMTA1\r\n"
"MTU0NVowFDESMBAGA1UEAwwJTUFMRk9STUVEMIIBSzCCAQMGByqGSM49AgEwgfcC\r\n"
"AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////\r\n"
"MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr\r\n"
"vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE\r\n"
"axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W\r\n"
"K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8\r\n"
"YyVRAgEBA0IABL/gnM66tzV2I+W/+nnMwDP0XT/HHyQlE3CXNm+JTRHKNRMyJRX6\r\n"
"Y5y5RIPdXfsfja9XJt4gjYuazSo8uAqkbRqjUzBRMB0GA1UdDgQWBBRZfvu1C6ya\r\n"
"pgoCyrWwx+fyQ95PJzAfBgNVHSMEGDAWgBRZfvu1C6yapgoCyrWwx+fyQ95PJzAP\r\n"
"BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCN9TitNg9mjUHSIQ9k\r\n"
"qieJjJtgkaOLA1f/h8Bs/sKNTQIhAMLhp4UgPphR1XhkLd9WN4oclaJ1M/ceLcKV\r\n"
"6pcPVk1J\r\n"
"-----END CERTIFICATE-----\r\n";
At first, I thought that the code for handling public keys that explicitly contains the EC parameters wasn't implemented in cryptopp-pem
. However, later I realized that it seems to be implemented, but there are some issues with the implementation.
The issue lies in the line 1231 in function GetSubjectPublicKeyInfoOids
, due to the inconsistency in the structure between EC public key that explicitly contain EC parameters and normal EC public key, the GetSubjectPublicKeyInfoOids
function incorrectly parse the value of field
as NULL
after execution.
The reason for incorrectly parsing field
to NULL
lies in the GetSubjectPublicKeyInfoOids
function, which expects to set algorithm
and field
to their corresponding OIDs
through two separate decode operations in line 1279 and line 1282. This is because, in a normal public key as shown below, algorithm
and field
occur consecutively, allowing them to be properly set as their corresponding OIDs
through this method:
123 86: SEQUENCE {
125 16: SEQUENCE {
127 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) // algorithm
136 5: OBJECT IDENTIFIER secp256k1 (1 3 132 0 10) // field
: }
143 66: BIT STRING
: 04 76 1F D6 09 08 4B 41 1D 99 83 1F 38 6E DB 9A
: 4A FB 7F 94 1A 0F CE 79 16 93 F3 B9 BD BB 8F 3E
: FE 4A F2 FE 1C B0 9B 93 5E 37 FE 5E 14 47 84 2E
: 28 E8 B7 49 F4 52 5E 53 B7 F0 C3 0F D9 CC DF 03
: 57
: }
When an EC public key explicitly contains parameters, its public key structure becomes as follows:
127 259: SEQUENCE {
131 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) // algorithm
140 247: SEQUENCE {
143 1: INTEGER 1
146 44: SEQUENCE {
148 7: OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1) // field
157 33: INTEGER
: 00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00
: 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF
: FF
: }
...
It can be seen that, in this case, what directly follows the algorithm
is no longer an OID
but a SEQUENCE
, and field
resides within this SEQUENCE
. Therefore, when attempting to set algorithm
and field
as their corresponding OIDs through two consecutive decode operations, the program incorrectly decodes the SEQUENCE
as an OID
. Clearly, this results in decoding failure, leading to the setting of field
as NULL
.
Once field is set to NULL
, this leads to subsequent functions in BERDecodeSubjectPublicKeyInfo
such as IsECPrimeFieldAlgorithm
or IsECBinaryFieldAlgorithm
, erroneously considering that the public key does not belong to an EC public key, thus terminating and reporting an error.
In PEM_read, there is a call to std::min with types (lword and size_t). Depending on the platform those types are of different size and lead to a compilation error.
Following patch works for me:
// If the IV size is wrong, SetKeyWithIV will throw an exception.
- const size_t size = (std::min)(hex.MaxRetrievable(), static_cast<size_t>(vsize));
+ const size_t size = (std::min)(hex.MaxRetrievable(), static_cast<lword>(vsize));
Hello,
I've tried creating a cert as follows with openssl
openssl genpkey -algorithm rsa-pss -pkeyopt rsa_keygen_bits:2048 -out root.key
openssl req -new -key root.key -out root.csr -config root_req.config
openssl ca -in root.csr -out root.crt -config root.config -selfsign -extfile ca.ext -days 7305
openssl x509 -in root.crt -outform PEM -out root.pem
then in my C++ code:
StringSource ss(certStr, true);
PEM_Load(ss, m_Cert);
It will fail eventually down the path and with some debugging it appears it fails at the BERDecodeSignatureAlgorithm(tbsCertificate, m_subjectSignatureAlgortihm);. More specifically at bool parametersPresent = seq.EndReached() ? false : BERDecodeAlgorithmParameters(seq);
where it reaches BERDecodeAlgorithmParameters.
I have not tried dumpasn as I do not have it installed, but I assume sequence is different and is causing problems.
Basically, I am trying to generate certificate that uses PSS with SHA256 in order to avoid SonarLint complaining about PCKS1v15 being not secure enough. I am trying to make my web server generate a certificate for the user and the user inputs the cert to an app for verification that it was signed by the server CA. I am new to crypto and certs so I may be doing some things wrong. It seems OAEP is the right thing to use but I have no idea how to generate this or use it with cryptopp and x509certificate libs?
Thanks,
Frank
pem.h
, pem_read.h
and pem_write.h
have references to ElGamal::Private
/PublicKey
type.
But, in the current release of Crypto++, 8.2.0, those types are actually under ElGamal**Keys**::Private/PublicKey
.
The pem_create.sh script downloads the most recent Mozilla root certificates from https://curl.se/ca/cacert.pem. As of Apr 26 2022 (or maybe before that) these certificates cause the pem_verify.sh to fail in X509Certificate::GetSubjectKeyUsage().
Load root certificates from Mozilla
Assertion failed: x509cert.cpp(1854): GetSubjectKeyUsage
./pem_verify.sh: line 30: 45335 Trace/breakpoint trap (core dumped) ./pem_test.exe
Failed to execute pem_test.exe
The CRYPTOPP_ASSERT(values.size() == 1) fails here as some of the certificates give a values.size() of 2 after BERDecodeBitString(store, values, unused).
Output of some custom debugging output:
serial number: 4151900041497450638097112925.
values.size(): 2, unused: 7
values[0]: 00000110
values[1]: 00000000
Hello,
I did try to use this lib with crypto++, I was able to parse x509 certificate. When it come to parse custom extension, it shows chunk of byes. How can I decode those bytes. I did try to use BERDecode it throws exception.
I would like to know, Is there any possibility to parse custom ASN1 extension? How we can do it?
One closing bracket too many in x509cert.cpp, line 89; it doesn't compile.
I'm trying to use Crypto++ with cryptopp-pem in Windows Visual Studio 2017 (moving the project from a Unix-based environment to Windows) and I'm facing several problems.
After manually adding the sources and headers in their respective cryptlib folders, I had to add #include "pch.h"
at the beginning of pem_commong.cpp
, pem_read.cpp
and pem.write.cpp
in order to not get the errors related to the precompiled header (pch.h).
Now, when I try to build cryptlib I get several errors related to C++, regardless of the configuration (it happens either in Debug or Release builds).
When trying to build or compile pem_read.cpp
the following errors appear:
1>------ Build started: Project: cryptlib, Configuration: Release x64 ------
1>pem_read.cpp
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(324): error C2039: 'toupper': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(605): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(611): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(623): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(626): error C2039: 'toupper': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(633): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(639): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(642): error C2039: 'toupper': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(653): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(656): error C2039: 'toupper': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_read.cpp(699): error C2039: 'isspace': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>Done building project "cryptlib.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
When trying to build or compile pem_write.cpp
the following errors appear:
1>------ Build started: Project: cryptlib, Configuration: Release x64 ------
1>pem_write.cpp
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\pem_write.cpp(321): error C2039: 'toupper': is not a member of 'std'
1>c:\users\user\desktop\cryptopp-master\cryptopp-master\gf2n.h(392): note: see declaration of 'std'
1>Done building project "cryptlib.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
On the other hand, pem_common.cpp
compiles or builds without problems.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.