private static DSA BuildDsaPublicKey(byte[] encodedKey, byte[] encodedParameters) { // Dss-Parms ::= SEQUENCE { // p INTEGER, // q INTEGER, // g INTEGER // } // The encodedKey value is a DER INTEGER representing the Y value DerSequenceReader parametersReader = new DerSequenceReader(encodedParameters); DerSequenceReader keyReader = DerSequenceReader.CreateForPayload(encodedKey); DSAParameters parameters = new DSAParameters(); // While this could use the object initializer, the read modifies the data stream, so // leaving these in flat call for clarity. parameters.P = parametersReader.ReadIntegerBytes(); parameters.Q = parametersReader.ReadIntegerBytes(); parameters.G = parametersReader.ReadIntegerBytes(); parameters.Y = keyReader.ReadIntegerBytes(); // Make the structure look like it would from Windows / .NET Framework TrimPaddingByte(ref parameters.P); TrimPaddingByte(ref parameters.Q); PadOrTrim(ref parameters.G, parameters.P.Length); PadOrTrim(ref parameters.Y, parameters.P.Length); DSA dsa = new DSAOpenSsl(); dsa.ImportParameters(parameters); return(dsa); }
protected override string DerStringToManagedString(byte[] anyString) { DerSequenceReader reader = DerSequenceReader.CreateForPayload(anyString); var tag = (DerSequenceReader.DerTag)reader.PeekTag(); string value = null; switch (tag) { case DerSequenceReader.DerTag.BMPString: value = reader.ReadBMPString(); break; case DerSequenceReader.DerTag.IA5String: value = reader.ReadIA5String(); break; case DerSequenceReader.DerTag.PrintableString: value = reader.ReadPrintableString(); break; case DerSequenceReader.DerTag.UTF8String: value = reader.ReadUtf8String(); break; // Ignore anything we don't know how to read. } return(value); }
public virtual void DecodeX509KeyUsageExtension(byte[] encoded, out X509KeyUsageFlags keyUsages) { DerSequenceReader reader = DerSequenceReader.CreateForPayload(encoded); byte[] decoded = reader.ReadBitString(); // Only 9 bits are defined. if (decoded.Length > 2) { throw new CryptographicException(); } // DER encodings of BIT_STRING values number the bits as // 01234567 89 (big endian), plus a number saying how many bits of the last byte were padding. // // So digitalSignature (0) doesn't mean 2^0 (0x01), it means the most significant bit // is set in this byte stream. // // BIT_STRING values are compact. So a value of cRLSign (6) | keyEncipherment (2), which // is 0b0010001 => 0b0010 0010 (1 bit padding) => 0x22 encoded is therefore // 0x02 (length remaining) 0x01 (1 bit padding) 0x22. // // We will read that, and return 0x22. 0x22 lines up // exactly with X509KeyUsageFlags.CrlSign (0x20) | X509KeyUsageFlags.KeyEncipherment (0x02) // // Once the decipherOnly (8) bit is added to the mix, the values become: // 0b001000101 => 0b0010 0010 1000 0000 (7 bits padding) // { 0x03 0x07 0x22 0x80 } // And we read new byte[] { 0x22 0x80 } // // The value of X509KeyUsageFlags.DecipherOnly is 0x8000. 0x8000 in a little endian // representation is { 0x00 0x80 }. This means that the DER storage mechanism has effectively // ended up being little-endian for BIT_STRING values. Untwist the bytes, and now the bits all // line up with the existing X509KeyUsageFlags. int value = 0; if (decoded.Length > 0) { value = decoded[0]; } if (decoded.Length > 1) { value |= decoded[1] << 8; } keyUsages = (X509KeyUsageFlags)value; }
private static int ReadInhibitAnyPolicyExtension(X509Extension extension) { DerSequenceReader reader = DerSequenceReader.CreateForPayload(extension.RawData); return(reader.ReadInteger()); }
internal static byte[] DecodeX509SubjectKeyIdentifierExtension(byte[] encoded) { DerSequenceReader reader = DerSequenceReader.CreateForPayload(encoded); return(reader.ReadOctetString()); }