internal void ValidateAndSkipDerValue() { byte tag = PeekTag(); // If the tag is in the UNIVERSAL class if ((tag & TagClassMask) == 0) { // Tag 0 is special ("reserved for use by the encoding rules"), but mainly is used // as the End-of-Contents marker for the indefinite length encodings, which DER prohibits. // // Tag 15 is reserved. // // So either of these are invalid. if (tag == 0 || tag == 15) { throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding)); } // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets // a defined encoding as being an IMPLICIT SEQUENCE. bool expectConstructed = false; switch (tag & TagNumberMask) { case 0x08: // External or Instance-Of case 0x0B: // EmbeddedPDV case (byte)DerTag.Sequence: case (byte)DerTag.Set: case 0x1D: // Unrestricted Character String expectConstructed = true; break; } bool isConstructed = (tag & ConstructedFlag) == ConstructedFlag; if (expectConstructed != isConstructed) { throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding)); } } EatTag((DerTag)tag); int contentLength = EatLength(); if (contentLength > 0 && (tag & ConstructedFlag) == ConstructedFlag) { var childReader = new DerSequenceReader(true, _data, _position, _end - _position); while (childReader.HasData) { childReader.ValidateAndSkipDerValue(); } } _position += contentLength; }
internal static byte[][] SegmentedEncodeSubjectPublicKeyInfo(this PublicKey publicKey) { if (publicKey == null) { throw new ArgumentNullException(nameof(publicKey)); } if (publicKey.Oid == null || string.IsNullOrEmpty(publicKey.Oid.Value) || publicKey.EncodedKeyValue == null) { throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidPublicKey_Object)); } // SubjectPublicKeyInfo::= SEQUENCE { // algorithm AlgorithmIdentifier, // subjectPublicKey BIT STRING // } // // AlgorithmIdentifier::= SEQUENCE { // algorithm OBJECT IDENTIFIER, // parameters ANY DEFINED BY algorithm OPTIONAL // } byte[][] algorithmIdentifier; if (publicKey.EncodedParameters == null) { algorithmIdentifier = DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(publicKey.Oid)); } else { DerSequenceReader validator = DerSequenceReader.CreateForPayload(publicKey.EncodedParameters.RawData); validator.ValidateAndSkipDerValue(); if (validator.HasData) { throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding)); } algorithmIdentifier = DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(publicKey.Oid), publicKey.EncodedParameters.RawData.WrapAsSegmentedForSequence()); } return(DerEncoder.ConstructSegmentedSequence( algorithmIdentifier, DerEncoder.SegmentedEncodeBitString( publicKey.EncodedKeyValue.RawData))); }
internal static void ValidateSignatureAlgorithm(byte[] signatureAlgorithm) { Debug.Assert(signatureAlgorithm != null); // AlgorithmIdentifier ::= SEQUENCE { OBJECT IDENTIFIER, ANY } DerSequenceReader validator = new DerSequenceReader(signatureAlgorithm); validator.ReadOidAsString(); if (validator.HasData) { validator.ValidateAndSkipDerValue(); } if (validator.HasData) { throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding)); } }
private void Decode() { if (_decoded) { return; } // AuthorityKeyIdentifier ::= SEQUENCE { // keyIdentifier [0] KeyIdentifier OPTIONAL, // authorityCertIssuer [1] GeneralNames OPTIONAL, // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } // // KeyIdentifier ::= OCTET STRING string keyId = null; X500DistinguishedName firstIssuerName = null; DerSequenceReader reader = new DerSequenceReader(RawData); byte[] serialNumber = null; // Primitive Context 0 const byte KeyIdTag = DerSequenceReader.ContextSpecificTagFlag | 0; // Constructed Context 1 const byte CertIssuerTag = DerSequenceReader.ContextSpecificConstructedTag1; // Primitive Context 2 const byte CertSerialTag = DerSequenceReader.ContextSpecificTagFlag | 2; if (reader.HasTag(KeyIdTag)) { keyId = reader.ReadOctetString().ToHexStringUpper(); } if (reader.HasTag(CertIssuerTag)) { DerSequenceReader generalNames = reader.ReadSequence(); while (generalNames.HasData) { const byte DirectoryNameTag = DerSequenceReader.ConstructedFlag | (byte)GeneralNameEncoder.GeneralNameTag.DirectoryName; if (firstIssuerName == null && generalNames.HasTag(DirectoryNameTag)) { firstIssuerName = new X500DistinguishedName(generalNames.ReadNextEncodedValue()); } reader.ValidateAndSkipDerValue(); } } if (reader.HasTag(CertSerialTag)) { serialNumber = reader.ReadOctetString(); } if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } _firstIssuerName = firstIssuerName; _serialNumber = serialNumber; _keyIdentifier = keyId; _decoded = true; }