none
Disable certificate chain check for ComputeSignature RRS feed

  • Question

  • Hi,

    I am developing an application that needs to sign a message according to PKCS#7 with the certificate chain included. However, it cannot be assumed that the certificate used has a trusted root certificate on the end-user's computer. I need to be able to sign the message anyway. Is it possible to disable the certificate chain check and sign the message anyway?

    This is my current source:

    X509Certificate2 cert = GetSignerCert();
    
    // create ContentInfo (what is signed)
    const String msg = "586B8364529451C6F9A3BF83D74EB2B92A79432C8A25A976F9E47C8FF9508DED";
    byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
    ContentInfo content = new ContentInfo(msgBytes);
    
    // object representing a signed message
    SignedCms signedMessage = new SignedCms(content);            
     
    // create CmsSigner (who signs)
    CmsSigner signer = new CmsSigner(cert);            
    signer.IncludeOption = X509IncludeOption.WholeChain;
    
    // sign the message
    signedMessage.ComputeSignature(signer, false);
    
    // create and return serialized representation            
    string signedMessageBase64 = Convert.ToBase64String(signedMessage.Encode());
    

    But ComputeSignature() gives this exception:

    System.Security.Cryptography.CryptographicException was unhandled
      Message="A certificate chain could not be built to a trusted root authority.\r\n"
      Source="System.Security"
      StackTrace:
           at System.Security.Cryptography.Pkcs.PkcsUtils.CreateBagOfCertificates(CmsSigner signer)
           at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer, Boolean silent)
           at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
           at SigningAMessageByOneSigner.SignedCmsSingleSigner.Sign() in c:\TEMP\HowToSignMessagebyOneSigner\HowToSignMessagebyOneSigner\Program.cs:line 62
           at SigningAMessageByOneSigner.SignedCmsSingleSigner.Main(String[] args) in c:\TEMP\HowToSignMessagebyOneSigner\HowToSignMessagebyOneSigner\Program.cs:line 21
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException:


    Thanks!
    /Michael

    Thursday, June 4, 2009 3:23 PM

Answers

  • I think, in the case of a non-valid certificate (that's no have a valid chain), you can only show a message to the user alerting him or her to the problem with their certificate.

    I think you cannot sign without a valid trust chain beacuse this is not PKI compliant. You can only manage the cases of not trusted Bank certificate.
    Wednesday, June 17, 2009 8:48 AM

All replies

  • Sorry but it's not clear the type of the certificate you have.

    I see two possibilities:

    1. you have a self signed certificate: so you must put it in the trusted certificate store in Windows system (and the certificate is trusted by itself)
    2. you don't have a self signed certificate: you must put the complete chain and the root CA certificate in the trusted certificate store.

    PKCS#7 could contain the complete trust chain. Why cannot you distribute the PKCS#7 with the complete chain with your application?

    I hope my answer could help you
    Tuesday, June 16, 2009 6:09 AM
  • Thank you for your answer.

    The application is going to contact an "invoice web service" using WS-SecureConversation. To logon the application must sign a challenge to be authenticated. The web service accepts a challange response signed using a certificate from any common bank. The application is going to prompt the user for a certificate she wishes to use during logon. The application will not provide any certificates.

    I would like the application to be able to sign the challenge without validating the certificate chain of the chosen certificate. The application does not care if the certificate is valid, this will be up to the invoice web service to decide.

    In my case I am using a test certificate (.p12) that is not self-signed. I don't have access to the Root CA certificate so that I could place it in the Trusted Certificate store. Most commonly the end user's certificate will have a valid certificate chain up to a trusted root CA. However, this is not true for all bank certificates.
    Wednesday, June 17, 2009 7:31 AM
  • I think, in the case of a non-valid certificate (that's no have a valid chain), you can only show a message to the user alerting him or her to the problem with their certificate.

    I think you cannot sign without a valid trust chain beacuse this is not PKI compliant. You can only manage the cases of not trusted Bank certificate.
    Wednesday, June 17, 2009 8:48 AM
  • Use

    signer.IncludeOption = X509IncludeOption.EndCertOnly;

    or

    signer.IncludeOption = X509IncludeOption.None;

    and add any additional certificates manually to the

    signer.Certificates
    collection.

     

     

    • Proposed as answer by Jecho Jekov Saturday, May 1, 2010 11:24 AM
    Saturday, May 1, 2010 11:24 AM
  • signer.IncludeOption = X509IncludeOption.EndCertOnly;

    or

    signer.IncludeOption = X509IncludeOption.None;

    Use

    signer.Certificates
    
    collection.

     

     

    This is very tricky solution because causes signer include (or not include) certificate chain information to the signature.


    Regards


    • Edited by spot9969 Monday, December 29, 2014 9:40 AM
    Monday, December 29, 2014 9:40 AM