void m_decode(Byte[] rawData) { Asn1Reader asn = new Asn1Reader(rawData); if (asn.Tag != 48) { throw new Asn1InvalidTagException(asn.Offset); } if (!asn.MoveNext()) { throw new Asn1InvalidTagException(asn.Offset); } if (asn.Tag != (Byte)Asn1Type.OBJECT_IDENTIFIER) { throw new Asn1InvalidTagException(asn.Offset); } AlgorithmId = Asn1Utils.DecodeObjectIdentifier(asn.GetTagRawData()); //Oid2 oid2 = new Oid2(oid.Value, OidGroupEnum.SignatureAlgorithm, false); //AlgorithmId = String.IsNullOrEmpty(oid2.Value) // ? oid // : new Oid(oid2.Value, oid2.FriendlyName); Parameters = asn.MoveNext() ? asn.GetTagRawData() : Asn1Utils.EncodeNull(); RawData = rawData; }
void m_encode(Oid oid, Byte[] parameters) { Parameters = parameters == null || parameters.Length == 0 ? Asn1Utils.EncodeNull() : parameters; AlgorithmId = oid; List <Byte> rawBytes = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(oid)); rawBytes.AddRange(Parameters); RawData = Asn1Utils.Encode(rawBytes.ToArray(), 48); }
/// <summary> /// Gets ASN-encoded algorithm identifier based on current configuration. /// </summary> /// <param name="alternate"> /// Specifies whether alternate signature format is used. This parameter has meaning only for /// ECDSA keys. Otherwise, the parameter is ignored. Default value is <strong>false</strong>. /// </param> /// <returns>ASN-encoded algorithm identifier.</returns> public AlgorithmIdentifier GetAlgorithmIdentifier(Boolean alternate = false) { if (SignatureAlgorithm == null) { getSignatureAlgorithm(); } Oid algId = SignatureAlgorithm; List <Byte> parameters = new List <Byte>(); switch (PublicKeyAlgorithm.Value) { case AlgorithmOids.ECC: // ECDSA if (alternate) { // specifiedECDSA algId = new Oid(AlgorithmOids.ECDSA_SPECIFIED); // only here we override algorithm OID parameters .AddRange( new AlgorithmIdentifier(HashingAlgorithm.ToOid(), Asn1Utils.EncodeNull()).RawData ); } break; case AlgorithmOids.RSA: // RSA // only RSA supports parameters. For PKCS1 padding: NULL, for PSS padding: // RSASSA-PSS-params ::= SEQUENCE { // hashAlgorithm [0] HashAlgorithm DEFAULT sha1, // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, // saltLength [2] INTEGER DEFAULT 20, // trailerField [3] TrailerField DEFAULT trailerFieldBC // } if (PaddingScheme == SignaturePadding.PSS) { Byte[] hash = new AlgorithmIdentifier(HashingAlgorithm.ToOid(), null).RawData; parameters.AddRange(Asn1Utils.Encode(hash, 0xa0)); // mask generation function: mgf1 Byte[] mgf = new AlgorithmIdentifier(new Oid("1.2.840.113549.1.1.8"), hash).RawData; parameters.AddRange(Asn1Utils.Encode(mgf, 0xa1)); // salt parameters.AddRange(Asn1Utils.Encode(new Asn1Integer(20).RawData, 0xa2)); // general PSS parameters encode parameters = new List <Byte>(Asn1Utils.Encode(parameters.ToArray(), 48)); } else { parameters.AddRange(Asn1Utils.EncodeNull()); } break; } return(new AlgorithmIdentifier(algId, parameters.ToArray())); }
/// <summary> /// Hashes current blob in <see cref="ToBeSignedData"/> member, constructs algorithm identifier /// (usually, with "NoSign" suffix) and attaches hash value in the signature section. /// </summary> /// <param name="hashAlgorithm">Hash algorithm to use for hashing.</param> /// <exception cref="ArgumentException"> /// Hash algorithm is not valid or cannot be mapped to respective signature algorithm. /// </exception> /// <exception cref="ArgumentNullException"> /// <strong>hashAlgorithm</strong> parameter is null. /// </exception> public void Hash(Oid2 hashAlgorithm) { if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } Oid2 transofrmedOid = Oid2.MapHashToSignatureOid(hashAlgorithm); using (var hasher = HashAlgorithm.Create(hashAlgorithm.FriendlyName)) { if (hasher == null) { throw new ArgumentException("Specified hash algorithm is not valid hashing algorithm"); } List <Byte> signature = hasher.ComputeHash(ToBeSignedData).ToList(); signature.Insert(0, 0); Signature = new Asn1BitString(Asn1Utils.Encode(signature.ToArray(), (Byte)Asn1Type.BIT_STRING)); } SignatureAlgorithm = new AlgorithmIdentifier(transofrmedOid.ToOid(), Asn1Utils.EncodeNull()); BlobType = ContentBlobType.SignedBlob; }
public static String Format(this PublicKey publicKey) { StringBuilder sb = new StringBuilder(); String keyParamsString = ""; switch (publicKey.Oid.Value) { case AlgorithmOids.ECC: keyParamsString = AsnFormatter .BinaryToString(publicKey.EncodedParameters.RawData, EncodingType.HexAddress) .TrimEnd(); keyParamsString += $"\r\n {new Asn1ObjectIdentifier(publicKey.EncodedParameters.RawData).Value.Format(true)}"; break; case AlgorithmOids.RSA: keyParamsString = AsnFormatter.BinaryToString(Asn1Utils.EncodeNull(), EncodingType.Hex); break; default: keyParamsString = AsnFormatter .BinaryToString(publicKey.EncodedParameters.RawData, EncodingType.HexAddress) .Replace("\r\n", "\r\n ") .TrimEnd(); break; } String keyValueString = AsnFormatter .BinaryToString(publicKey.EncodedKeyValue.RawData, EncodingType.HexAddress) .Replace("\r\n", "\r\n ") .TrimEnd(); sb.Append( $@"Public Key Algorithm: Algorithm ObjectId: {publicKey.Oid.FriendlyName} ({publicKey.Oid.Value}) Algorithm Parameters: {keyParamsString} Public Key Length: {publicKey.GetKeyLength()} bits Public Key: UnusedBits = 0 {keyValueString} "); return(sb.ToString()); }
/// <summary> /// Encodes current object to a DER-encoded byte array. Returned array is used to construct initial OCSP Request structure. /// </summary> /// <returns>Returns a DER-encoded byte array.</returns> /// <value>System.Byte[]</value> public Byte[] Encode() { if (!String.IsNullOrEmpty(SerialNumber)) { if (issuerPublicKey != null) { initializeFromCertAndIssuer(); } // algorithm identifier var rawData = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(hashAlgorithm)); rawData.AddRange(Asn1Utils.EncodeNull()); rawData = new List <Byte>(Asn1Utils.Encode(rawData.ToArray(), 48)); // IssuerNameId rawData.AddRange(Asn1Utils.Encode(AsnFormatter.StringToBinary(IssuerNameId, EncodingType.HexRaw), 4)); // IssuerKeyId rawData.AddRange(Asn1Utils.Encode(AsnFormatter.StringToBinary(IssuerKeyId, EncodingType.HexRaw), 4)); // SerialNumber rawData.AddRange(Asn1Utils.Encode(serialNumber, 2)); IsReadOnly = true; return(Asn1Utils.Encode(rawData.ToArray(), 48)); } throw new UninitializedObjectException(); }