ComponentSpace

Forums



Certificate error when running in Docker container


Certificate error when running in Docker container

Author
Message
andreasn
andreasn
New Member
New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)New Member (2 reputation)

Group: Forum Members
Posts: 1, Visits: 1
We are trying out your SAML component for .Net Core and we get this exception when loading the certificate.

It works fine when running the code in Windows developer machine, but in a Docker container (running Linux) it throws this exception.

Certificate is read from database as byte array and converted into Base64 string.

Do you know a solution to this problem?

Is it possible to pass a byte array certificate or X509Certificate2 instance into IdP configuration?

Exception:

The X.509 certificate could not be loaded from the string. - error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error

at ComponentSpace.Saml2.Certificates.CertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)
 at ComponentSpace.Saml2.Certificates.AbstractCachedCertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)
 at ComponentSpace.Saml2.Certificates.CertificateManager.LoadCertificatesAsync(IList`1 certificates, CertificateUse certificateUse)
 at ComponentSpace.Saml2.Certificates.CertificateManager.GetPartnerIdentityProviderSignatureCertificatesAsync(String configurationID, String partnerIdentityProviderName)
 at ComponentSpace.Saml2.SamlServiceProvider.GetPartnerProviderSignatureCertificatesAsync(Boolean precondition)
 at ComponentSpace.Saml2.SamlServiceProvider.VerifySamlAssertionSignatureAsync(AssertionListItem assertionListItem)
 at ComponentSpace.Saml2.SamlServiceProvider.GetSamlAssertionAsync(SamlResponse samlResponse)
 at ComponentSpace.Saml2.SamlServiceProvider.ProcessSamlResponseAsync(XmlElement samlResponseElement)
 at ComponentSpace.Saml2.SamlServiceProvider.ReceiveSsoAsync()

--- Inner exception stack trace ---
 at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
 at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
 at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
 at ComponentSpace.Saml2.Certificates.CertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)

ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)

Group: Administrators
Posts: 2.8K, Visits: 8.8K
We use the following code to load the certificate string.


new X509Certificate2(
    Convert.FromBase64String(certificateString),
    certificatePassword,
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);


Please try running this code in a small test app to confirm you get the same issue outside of our library.
I also suggest comparing the base-64 certificate string on the Windows and Linux systems just in case something odd is happening when you convert from the byte array to the base-64 string.
You could implement the ICertificateManager interface and you would be free to construct certificates from byte arrays etc but I think it would be better to resolve this issue as implementing ICertificateManager would be more work.
Let us know what you find.

Regards
ComponentSpace Development
gluna
gluna
New Member
New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)

Group: Awaiting Activation
Posts: 3, Visits: 28
Have you find a fix for this? I'm having the same problem. Running the project on a docker an fails however on Windows this was working fine.


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)

Group: Administrators
Posts: 2.8K, Visits: 8.8K
We never heard back from the original poster.

Can you confirm that the base-64 encoded certificate string is correct?

Can you try the above code (ie X509Certificate2 constructor etc) in your app to confirm you see the same issue and it isn't specific to the SAML library?

Regards
ComponentSpace Development
gluna
gluna
New Member
New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)

Group: Awaiting Activation
Posts: 3, Visits: 28
Found the solution for my issue.
Posting this in case anyone makes the same foolish mistake.  In our workflow certs are uploaded via rest api, so they need to be encoded in base64. Those values are stored in a DB to then be used in the saml assertion. The X509Certificate2 in Windows seems to support encoded certs, but not in linux. The direct migration to Docker did not work.

//this used to work in Windows but not in Linux
var x509Certificate2 = new X509Certificate2(Convert.FromBase64String(CertificateBase64), password,  X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);[

//this is the workaround
 byte[] data = Convert.FromBase64String(CertificateBase64);
 string decodedString = Encoding.UTF8.GetString(data);
var x509Certificate2 = new X509Certificate2(Convert.FromBase64String(decodedString), password,  X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)

Group: Administrators
Posts: 2.8K, Visits: 8.8K
I'm not sure I understand your code. The Encoding.UTF8.GetString(data) isn't going to be a base-64 string. If I run this code on Windows, Convert.FromBase64String(decodedString) throws a FormatException. 

Regards
ComponentSpace Development
gluna
gluna
New Member
New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)New Member (3 reputation)

Group: Awaiting Activation
Posts: 3, Visits: 28
Let's say we have the following cert 1234/+abc== and we need to send it via rest api. You have to encode it => MTIzNC8rYWJjPT0= before posting the data.
In windows this used to work
var x509Certificate2 = new X509Certificate2("MTIzNC8rYWJjPT0=", password,  X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)

Group: Administrators
Posts: 2.8K, Visits: 8.8K
I'm not sure what the conversion is that you're doing.

Also, the X509Certificate2 constructor whose first parameter is a string specifies the certificate file name. I'm not sure how this code used to work.

https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.-ctor?view=net-5.0#System_Security_Cryptography_X509Certificates_X509Certificate2__ctor_System_String_System_String_System_Security_Cryptography_X509Certificates_X509KeyStorageFlags_


Regards
ComponentSpace Development
sach52
sach52
New Member
New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)New Member (1 reputation)

Group: Forum Members
Posts: 1, Visits: 3
andreasn - 4/2/2019
We are trying out your SAML component for .Net Core and we get this exception when loading the certificate.

It works fine when running the code in Windows developer machine, but in a Docker container (running Linux) it throws this exception.

Certificate is read from database as byte array and converted into Base64 string.

Do you know a solution to this problem?

Is it possible to pass a byte array certificate or X509Certificate2 instance into IdP configuration?

Exception:

The X.509 certificate could not be loaded from the string. - error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error

at ComponentSpace.Saml2.Certificates.CertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)
 at ComponentSpace.Saml2.Certificates.AbstractCachedCertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)
 at ComponentSpace.Saml2.Certificates.CertificateManager.LoadCertificatesAsync(IList`1 certificates, CertificateUse certificateUse)
 at ComponentSpace.Saml2.Certificates.CertificateManager.GetPartnerIdentityProviderSignatureCertificatesAsync(String configurationID, String partnerIdentityProviderName)
 at ComponentSpace.Saml2.SamlServiceProvider.GetPartnerProviderSignatureCertificatesAsync(Boolean precondition)
 at ComponentSpace.Saml2.SamlServiceProvider.VerifySamlAssertionSignatureAsync(AssertionListItem assertionListItem)
 at ComponentSpace.Saml2.SamlServiceProvider.GetSamlAssertionAsync(SamlResponse samlResponse)
 at ComponentSpace.Saml2.SamlServiceProvider.ProcessSamlResponseAsync(XmlElement samlResponseElement)
 at ComponentSpace.Saml2.SamlServiceProvider.ReceiveSsoAsync()

--- Inner exception stack trace ---
 at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
 at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
 at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
 at ComponentSpace.Saml2.Certificates.CertificateLoader.LoadCertificateFromStringAsync(String certificateString, String certificatePassword)

@andreasn : How do you store certificate in Database? Do you use nvarchar column type? Also do insert cert with -----BEGIN CERTIFICATE----- ....-----END CERTIFICATE----- ? 
If we insert cert with -----END CERTIFICATE----- this lines, it will fail  here byte[] bytes = Convert.FromBase64String(item.Certificate);


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)ComponentSpace Development (3.9K reputation)

Group: Administrators
Posts: 2.8K, Visits: 8.8K
Just store the base-64 string. This can be stored as an nvarchar.

Another option is to store the base-64 string directly in the SAML configuration (eg appsettings.json). For more information, refer to our Configuration Guide and Certificate Guide.

https://www.componentspace.com/Forums/8234/Configuration-Guide

https://www.componentspace.com/Forums/8238/Certificate-Guide


Regards
ComponentSpace Development
GO


Similar Topics


Execution: 0.000. 2 queries. Compression Enabled.
Login
Existing Account
Email Address:


Password:


Social Logins

Select a Forum....









Forums, Documentation & Knowledge Base - ComponentSpace


Search