[Mono-list] Unknown hash algorithm

Martín Trejo Chávez mtrejoch at ownmail.net
Wed May 3 17:41:39 EDT 2006


Hello Sebastian,

Let's start from the beginning. :P

I've a requirement of generating PKCS7's from PKCS12's in form of .pfx 
files.  We have our own CA, so in the .pfx files comes the CA's certificate 
and the user's certificate.

I've read the standard and looked some Mono code but still haven't figured 
out how to build a PKCS7. Seems to me like all the process must be done 
programmatically (?) and the PKCS7 class helps to "form" the data. Besides, 
we have some supplier's libraries that allow to create PKCS7, but all input 
& output is in form of files. So, I was trying to extract the user's 
certificate and private key to dump them into files and experiment with the 
libraries.

This the full code I was using to extract the user's data:

 public string ExtractCertificate() {
  X509Certificate userCertificate = null;
  X509Certificate issuerCertificate = null;
  X509CertificateBuilder builder = new X509CertificateBuilder();

  foreach(X509Certificate certificate in this.pfx.Certificates) {
   foreach(X509Extension extension in certificate.Extensions) {
    if(extension.Oid.Equals("2.5.29.19")) {
     BasicConstraintsExtension bcExtension = new 
BasicConstraintsExtension(extension);

     if(!bcExtension.CertificateAuthority) {
      // si no es entidad certificadora,
      // es certificado de usuario
      userCertificate = certificate;
     } else {
      issuerCertificate = certificate;
     }
    }
   }
  }

  AsymmetricAlgorithm aa = pfx.Keys[0] as RSA;

  builder.SerialNumber = userCertificate.SerialNumber;
  builder.IssuerName = userCertificate.IssuerName;
  builder.NotBefore = userCertificate.ValidFrom;
  builder.NotAfter = userCertificate.ValidUntil;
  builder.SubjectName = userCertificate.SubjectName;
  builder.SubjectPublicKey = aa;
  builder.Hash = userCertificate.SignatureAlgorithm;

  byte[] rawcert = builder.Sign(aa);

  // crear archivo temporal para depositar el cert
  Random rand = new Random();
  string path = 
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  string filename = rand.Next(10000).ToString() + ".cer"; // BAD:
  string fullPath = Path.Combine(path, filename);

  WriteCertificate(fullPath, rawcert);

  return fullPath;

 }

I wrapped the supplier's API with  .NET class like this:

 public class PsmSeguridad
 {
  [DllImport("psmseguridad.dll")]
  public static extern int autenticar_firma(string archivo_ensobretado, 
string archivo_enclaro, string certificado_destinatario, string 
llaveprivada_destinatario, string frasesecreta_destinatario);

  [DllImport("psmseguridad.dll")]
  public static extern int firmar_ensobretar(string archivo_enclaro, string 
archivo_ensobretado, string certificado_firmante, string 
llaveprivada_firmante, string frasesecreta_firmante, string 
certificado_destinatario);

  [DllImport("psmseguridad.dll")]
  public static extern string recuperar_error(int errnum);
 }

Thank you.

Regards,

Martín Trejo Chávez
http://chilli-coder.blogspot.com
http://www.chillicoder.com

----- Original Message ----- 
From: "Sebastien Pouliot" <sebastien.pouliot at gmail.com>
To: "Martín Trejo Chávez" <mtrejoch at ownmail.net>
Cc: <mono-list at lists.ximian.com>; <mono-deve-list at lists.ximian.com>
Sent: Wednesday, May 03, 2006 3:18 PM
Subject: Re: [Mono-list] Unknown hash algorithm


> Hello Martin,
>
> On Wed, 2006-05-03 at 14:33 -0500, Martín Trejo Chávez wrote:
>> Hi,
>>
>> I've been working in a proyect where is required to extract the user
>> certificate and his private key from a .pfx file. After have looked at
>> certmgr and makecert code, finally I made a class to do the task.
>>
>> I use a X509CertificateBuilder to receive the values from the user's
>> certificate, just transfer for one side to another:
>
> You can't rebuild a certificate from it's data - at least it wouldn't be
> the "same" certificate unless...
>
>>   builder.SerialNumber = userCertificate.SerialNumber;
>>   builder.IssuerName = userCertificate.IssuerName;
>>   builder.NotBefore = userCertificate.ValidFrom;
>>   builder.NotAfter = userCertificate.ValidUntil;
>>   builder.SubjectName = userCertificate.SubjectName;
>>   builder.SubjectPublicKey = aa;
>>   builder.Hash = userCertificate.SignatureAlgorithm;
>>
>>   byte[] rawcert = builder.Sign(aa);
>
> ... 'aa' is the CA private key. If not then you are creating a (invalid
> as the issuer != subject) self-signed certificate.
>
> Now what I don't understand is why you can't use the 'userCertificate'
> itself ?
>
> The PKCS12 instance you have already has the certificate(s) and the
> private key. What more do you need ?
>
>> The problem arise from the las line, as it's run throws this
>> exception:
>>
>> Unknown hash algorithm 1.2.840.113549.1.1.5
>> in <0x000ee> Mono.Security.X509.X509Builder:GetOid (System.String
>> hashName)
>> in <0x00038> Mono.Security.X509.X509Builder:Sign
>> (System.Security.Cryptography.RSA key)
>> in <0x0004d> Mono.Security.X509.X509Builder:Sign
>> (System.Security.Cryptography.AsymmetricAlgorithm aa)
>> in <0x00466> PfxManager:ExtractCertificate ()
>> in <0x0002f> PfxManagerTest:Main (System.String[] args)
>>
>> This is for Mono 1.1.13.6, Mono 1.1.15 and .NET 1.1
>>
>> I've already found the description of the OID at
>> http://www.alvestrand.no/objectid/1.2.840.113549.1.1.5.html.
>
> That's another issue (the assigned value is wrong).
>
>> Now, this simply means that as the hash algorithm is unknown I'm stuck
>> 'til here? I'm not very cripto-proficient so the idea of building a
>> hash algorithm implementation really scares me, besides, there is no
>> time :P
>
> Don't worry there's no need for that ;-)
>
>> Any comments, guidance and/or help would be appreciated.
>
> A more detailed description could be useful (e.g. input you have, output
> you require).
> -- 
> Sebastien Pouliot  <sebastien at ximian.com>
> Blog: http://pages.infinit.net/ctech/
>
> 



More information about the Mono-list mailing list