X509Certificate2 build(X509Certificate2 signer) { MessageSigner signerInfo = signer == null ? new MessageSigner(PrivateKeyInfo, HashingAlgorithm) : new MessageSigner(signer, HashingAlgorithm); signerInfo.PaddingScheme = AlternateSignatureFormat ? SignaturePadding.PSS : SignaturePadding.PKCS1; // initialize from v3 version var rawData = new List <Byte>(_versionBytes); // serial number rawData.AddRange(Asn1Utils.Encode(serialNumber, (Byte)Asn1Type.INTEGER)); // algorithm identifier rawData.AddRange(signerInfo.GetAlgorithmIdentifier(AlternateSignatureFormat).RawData); // issuer rawData.AddRange(signer == null ? SubjectName.RawData : signer.SubjectName.RawData); // NotBefore and NotAfter List <Byte> date = Asn1Utils.EncodeDateTime(NotBefore).ToList(); date.AddRange(Asn1Utils.EncodeDateTime(NotAfter)); rawData.AddRange(Asn1Utils.Encode(date.ToArray(), 48)); // subject rawData.AddRange(SubjectName.RawData); rawData.AddRange(PrivateKeyInfo.GetPublicKey().Encode()); rawData.AddRange(Asn1Utils.Encode(finalExtensions.Encode(), 0xa3)); var blob = new SignedContentBlob(Asn1Utils.Encode(rawData.ToArray(), 48), ContentBlobType.ToBeSignedBlob); blob.Sign(signerInfo); return(new X509Certificate2(blob.Encode())); }
/// <summary> /// Signs <see cref="ToBeSignedData"/> data by using client-provided message signer. /// </summary> /// <param name="signerInfo">Configured message signer object which is used to sign the data.</param> public void Sign(MessageSigner signerInfo) { var signature = signerInfo.SignData(ToBeSignedData).ToList(); if (signerInfo.SignerCertificate.PublicKey.Oid.Value == AlgorithmOids.RSA) { signature.Insert(0, 0); Signature = new Asn1BitString(Asn1Utils.Encode(signature.ToArray(), 3)); } else { // ECDSA, DSA signature consist of two parts, r and s. Int32 divider = signature.Count / 2; List <Byte> r = signature.Skip(0).Take(divider).ToList(); // check if most significant bit is set to 1. If set, prepend value with extra 0 byte. if (r[0] > 127) { r.Insert(0, 0); } List <Byte> s = signature.Skip(divider).Take(divider).ToList(); // check if most significant bit is set to 1. If set, prepend value with extra 0 byte. if (s[0] > 127) { s.Insert(0, 0); } var builder = new List <Byte>(); builder.AddRange(Asn1Utils.Encode(r.ToArray(), (Byte)Asn1Type.INTEGER)); builder.AddRange(Asn1Utils.Encode(s.ToArray(), (Byte)Asn1Type.INTEGER)); builder = new List <Byte>(Asn1Utils.Encode(builder.ToArray(), 48)); builder.Insert(0, 0); Signature = new Asn1BitString(Asn1Utils.Encode(builder.ToArray(), 3)); } SignatureAlgorithm = signerInfo.GetAlgorithmIdentifier(); BlobType = ContentBlobType.SignedBlob; }