internal byte[][] Encode() { return(DerEncoder.ConstructSegmentedSequence( HashAlgorithm.Encode(), DerEncoder.SegmentedEncodeOctetString(CertificateHash), IssuerSerial.Encode())); }
private static byte[][] ParseRdn( byte[][] encodedOid, char[] chars, int valueStart, int valueEnd, bool ia5String) { byte[][] encodedValue; int length = valueEnd - valueStart; if (ia5String) { // An email address with an invalid value will throw. encodedValue = DerEncoder.SegmentedEncodeIA5String(chars, valueStart, length); } else if (DerEncoder.IsValidPrintableString(chars, valueStart, length)) { encodedValue = DerEncoder.SegmentedEncodePrintableString(chars, valueStart, length); } else { encodedValue = DerEncoder.SegmentedEncodeUtf8String(chars, valueStart, length); } return(DerEncoder.ConstructSegmentedSet( DerEncoder.ConstructSegmentedSequence( encodedOid, encodedValue))); }
internal byte[][] Encode() { var bytes = DirectoryName.RawData; var reader = DerSequenceReader.CreateForPayload(bytes); var tag = reader.PeekTag(); var value = reader.ReadValue((DerSequenceReader.DerTag)tag); var lengthByteCount = reader.ContentLength - 1 - value.Length; var length = new byte[lengthByteCount]; Array.Copy(bytes, sourceIndex: 1, destinationArray: length, destinationIndex: 0, length: length.Length); const int contextId = 4; return(DerEncoder.ConstructSegmentedContextSpecificValue( contextId, new byte[][] { new byte[1] { tag }, length, value })); }
public byte[] EncodeX509BasicConstraints2Extension( bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint) { //BasicConstraintsSyntax::= SEQUENCE { // cA BOOLEAN DEFAULT FALSE, // pathLenConstraint INTEGER(0..MAX) OPTIONAL, // ... } List <byte[][]> segments = new List <byte[][]>(2); if (certificateAuthority) { segments.Add(DerEncoder.SegmentedEncodeBoolean(true)); } if (hasPathLengthConstraint) { byte[] pathLengthBytes = BitConverter.GetBytes(pathLengthConstraint); // Little-Endian => Big-Endian Array.Reverse(pathLengthBytes); segments.Add(DerEncoder.SegmentedEncodeUnsignedInteger(pathLengthBytes)); } return(DerEncoder.ConstructSequence(segments)); }
internal byte[][] Encode() { // Per RFC 5280 section 4.1.2.2 (https://tools.ietf.org/html/rfc5280#section-4.1.2.2) // serial number must be an unsigned integer. return(DerEncoder.ConstructSegmentedSequence( DerEncoder.ConstructSegmentedSequence(GeneralNames.First().Encode()), DerEncoder.SegmentedEncodeUnsignedInteger(SerialNumber))); }
/// <summary> /// Encodes the AlgorithmIdentifier, as defined in PKCS#5 (RFC 2898). /// </summary> /// <param name="Der">DER output.</param> public override void EncodePkcs5AlgorithmIdentifier(DerEncoder Der) { Der.StartSEQUENCE(); Der.OBJECT_IDENTIFIER(this.AlgorithmOID); Der.StartSEQUENCE(); // pkcs-12PbeParams Der.OCTET_STRING(this.salt); Der.INTEGER(this.iterations); Der.EndSEQUENCE(); // End of pkcs-12PbeParams Der.EndSEQUENCE(); }
public byte[] Encode() { var entries = new List <byte[][]>(Certificates.Count); foreach (var essCertIdV2 in Certificates) { entries.Add(essCertIdV2.Encode()); } return(DerEncoder.ConstructSequence(DerEncoder.ConstructSegmentedSequence(entries))); }
/// <summary> /// Create a signing-certificate-v2 from a certificate. /// </summary> public static CryptographicAttributeObject GetSigningCertificateV2(IEnumerable <X509Certificate2> chain, Common.HashAlgorithmName hashAlgorithm) { // Build the cert chain as-is var certEntries = chain.Select(e => CreateESSCertIDv2Entry(e, hashAlgorithm)).ToList(); var data = new AsnEncodedData(Oids.SigningCertificateV2, DerEncoder.ConstructSequence(certEntries)); // Create an attribute return(new CryptographicAttributeObject( oid: new Oid(Oids.SigningCertificateV2), values: new AsnEncodedDataCollection(data))); }
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.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.Cryptography_Der_Invalid_Encoding); } algorithmIdentifier = DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(publicKey.Oid), publicKey.EncodedParameters.RawData.WrapAsSegmentedForSequence()); } return(DerEncoder.ConstructSegmentedSequence( algorithmIdentifier, DerEncoder.SegmentedEncodeBitString( publicKey.EncodedKeyValue.RawData))); }
/// <summary> /// Allows encoding data that the production helper does not. /// </summary> private static CryptographicAttributeObject GetCommitmentTypeTestAttribute(params string[] oids) { var commitmentTypeIndication = new Oid(Oids.CommitmentTypeIndication); var values = new AsnEncodedDataCollection(); foreach (var oid in oids) { var value = DerEncoder.ConstructSequence(DerEncoder.SegmentedEncodeOid(oid)); values.Add(new AsnEncodedData(commitmentTypeIndication, value)); } return(new CryptographicAttributeObject(commitmentTypeIndication, values)); }
public static void ValidateUintEncodings(string hexRaw, byte tag, string hexLength, string hexValue) { byte[] raw = hexRaw.HexToByteArray(); byte[] length = hexLength.HexToByteArray(); byte[] value = hexValue.HexToByteArray(); byte[][] segments = DerEncoder.SegmentedEncodeUnsignedInteger(raw); Assert.Equal(3, segments.Length); Assert.Equal(new[] { tag }, segments[0]); Assert.Equal(length, segments[1]); Assert.Equal(value, segments[2]); }
internal static byte[][] SegmentedEncodedX509Extension(this X509Extension extension) { if (extension.Critical) { return(DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(extension.Oid), DerEncoder.SegmentedEncodeBoolean(extension.Critical), DerEncoder.SegmentedEncodeOctetString(extension.RawData))); } return(DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(extension.Oid), DerEncoder.SegmentedEncodeOctetString(extension.RawData))); }
/// <summary> /// Convert Ieee1363 format of (r, s) to Der format /// </summary> public static byte[] ConvertIeee1363ToDer(ReadOnlySpan <byte> input) { Debug.Assert(input.Length % 2 == 0); Debug.Assert(input.Length > 1); // Input is (r, s), each of them exactly half of the array. // Output is the DER encoded value of CONSTRUCTEDSEQUENCE(INTEGER(r), INTEGER(s)). int halfLength = input.Length / 2; byte[][] rEncoded = DerEncoder.SegmentedEncodeUnsignedInteger(input.Slice(0, halfLength)); byte[][] sEncoded = DerEncoder.SegmentedEncodeUnsignedInteger(input.Slice(halfLength, halfLength)); return(DerEncoder.ConstructSequence(rEncoded, sEncoded)); }
public static void ConstructSequence() { byte[] expected = { /* SEQUENCE */ 0x30, 0x07, /* INTEGER(0) */ 0x02, 0x01, 0x00, /* INTEGER(256) */ 0x02, 0x02, 0x01, 0x00, }; byte[] encoded = DerEncoder.ConstructSequence( DerEncoder.SegmentedEncodeUnsignedInteger(new byte[] { 0x00 }), DerEncoder.SegmentedEncodeUnsignedInteger(new byte[] { 0x01, 0x00 })); Assert.Equal(expected, encoded); }
public byte[] EncodeX509SubjectKeyIdentifierExtension(byte[] subjectKeyIdentifier) { //subjectKeyIdentifier EXTENSION ::= { // SYNTAX SubjectKeyIdentifier // IDENTIFIED BY id - ce - subjectKeyIdentifier } // //SubjectKeyIdentifier::= KeyIdentifier // //KeyIdentifier ::= OCTET STRING byte[][] segments = DerEncoder.SegmentedEncodeOctetString(subjectKeyIdentifier); // The extension is not a sequence, just the octet string return(ConcatenateArrays(segments)); }
public static void ValidateOctetStringEncodings(string hexData, string hexLength) { byte[] input = hexData.HexToByteArray(); const byte tag = 0x04; byte[] length = hexLength.HexToByteArray(); byte[][] segments = DerEncoder.SegmentedEncodeOctetString(input); Assert.Equal(3, segments.Length); Assert.Equal(new[] { tag }, segments[0]); Assert.Equal(length, segments[1]); Assert.Equal(input, segments[2]); }
// ESSCertIDv2::= SEQUENCE { // hashAlgorithm AlgorithmIdentifier // DEFAULT {algorithm id-sha256 }, // certHash Hash, // issuerSerial IssuerSerial OPTIONAL // } private static byte[][] CreateESSCertIDv2Entry(X509Certificate2 cert, Common.HashAlgorithmName hashAlgorithm) { // Get hash Oid var hashAlgorithmOid = hashAlgorithm.ConvertToOidString(); var entry = GetESSCertIDv2Entry(cert, hashAlgorithm); return(DerEncoder.ConstructSegmentedSequence(new List <byte[][]>() { // AlgorithmIdentifier DerEncoder.SegmentedEncodeOid(hashAlgorithmOid), // Hash DerEncoder.SegmentedEncodeOctetString(entry.Value) })); }
internal static byte[][] SegmentedEncodeAttributeSet(this IEnumerable <X501Attribute> attributes) { List <byte[][]> encodedAttributes = new List <byte[][]>(); foreach (X501Attribute attribute in attributes) { encodedAttributes.Add( DerEncoder.ConstructSegmentedSequence( DerEncoder.SegmentedEncodeOid(attribute.Oid), DerEncoder.ConstructSegmentedPresortedSet( attribute.RawData.WrapAsSegmentedForSequence()))); } return(DerEncoder.ConstructSegmentedSet(encodedAttributes.ToArray())); }
public static void ValidateNamedBitEncodings(string hexRaw, int namedBits, string hexLength, string encodedData) { byte[] input = hexRaw.HexToByteArray(); const byte tag = 0x03; byte[] length = hexLength.HexToByteArray(); byte[] expectedOutput = encodedData.HexToByteArray(); byte[][] segments = DerEncoder.SegmentedEncodeNamedBitList(input, namedBits); Assert.Equal(3, segments.Length); Assert.Equal(new[] { tag }, segments[0]); Assert.Equal(length, segments[1]); Assert.Equal(expectedOutput, segments[2]); }
public static void ValidateOidEncodings(string oidValue, string hexLength, string encodedData) { Oid oid = new Oid(oidValue, oidValue); const byte tag = 0x06; byte[] length = hexLength.HexToByteArray(); byte[] expectedOutput = encodedData.HexToByteArray(); byte[][] segments = DerEncoder.SegmentedEncodeOid(oid); Assert.Equal(3, segments.Length); Assert.Equal(new[] { tag }, segments[0]); Assert.Equal(length, segments[1]); Assert.Equal(expectedOutput, segments[2]); }
/// <summary> /// Allows encoding bad data that the production helper does not. /// </summary> private static CryptographicAttributeObject GetCommitmentTypeTestAttribute(params string[] oids) { var values = new List <byte[][]>(); foreach (var oid in oids) { values.Add(DerEncoder.SegmentedEncodeOid(oid)); } var commitmentTypeData = DerEncoder.ConstructSequence(values); var data = new AsnEncodedData(Oids.CommitmentTypeIndication, commitmentTypeData); // Create an attribute return(new CryptographicAttributeObject( oid: new Oid(Oids.CommitmentTypeIndication), values: new AsnEncodedDataCollection(data))); }
public byte[] EncodeX509KeyUsageExtension(X509KeyUsageFlags keyUsages) { // The numeric values of X509KeyUsageFlags mean that if we interpret it as a little-endian // ushort it will line up with the flags in the spec. ushort ushortValue = unchecked ((ushort)(int)keyUsages); byte[] data = BitConverter.GetBytes(ushortValue); // RFC 3280 section 4.2.1.3 (https://tools.ietf.org/html/rfc3280#section-4.2.1.3) defines // digitalSignature (0) through decipherOnly (8), making 9 named bits. const int namedBitsCount = 9; // The expected output of this method isn't the SEQUENCE value, but just the payload bytes. byte[][] segments = DerEncoder.SegmentedEncodeNamedBitList(data, namedBitsCount); Debug.Assert(segments.Length == 3); return(ConcatenateArrays(segments)); }
public byte[] EncodeX509EnhancedKeyUsageExtension(OidCollection usages) { //extKeyUsage EXTENSION ::= { // SYNTAX SEQUENCE SIZE(1..MAX) OF KeyPurposeId // IDENTIFIED BY id - ce - extKeyUsage } // //KeyPurposeId::= OBJECT IDENTIFIER List <byte[][]> segments = new List <byte[][]>(usages.Count); foreach (Oid usage in usages) { segments.Add(DerEncoder.SegmentedEncodeOid(usage)); } return(DerEncoder.ConstructSequence(segments)); }
public byte[] ComputeCapiSha1OfPublicKey(PublicKey key) { // The CapiSha1 value is the SHA-1 of the SubjectPublicKeyInfo field, inclusive // of the DER structural bytes. //SubjectPublicKeyInfo::= SEQUENCE { // algorithm AlgorithmIdentifier{ { SupportedAlgorithms} }, // subjectPublicKey BIT STRING, // ... } // //AlgorithmIdentifier{ ALGORITHM: SupportedAlgorithms} ::= SEQUENCE { // algorithm ALGORITHM.&id({ SupportedAlgorithms}), // parameters ALGORITHM.&Type({ SupportedAlgorithms} // { @algorithm}) OPTIONAL, // ... } // //ALGORITHM::= CLASS { // &Type OPTIONAL, // &id OBJECT IDENTIFIER UNIQUE } //WITH SYNTAX { // [&Type] //IDENTIFIED BY &id } // key.EncodedKeyValue corresponds to SubjectPublicKeyInfo.subjectPublicKey, except it // has had the BIT STRING envelope removed. // // key.EncodedParameters corresponds to AlgorithmIdentifier.Parameters precisely // (DER NULL for RSA, DER Constructed SEQUENCE for DSA) byte[] empty = Array.Empty <byte>(); byte[][] algorithmOid = DerEncoder.SegmentedEncodeOid(key.Oid); // Because ConstructSegmentedSequence doesn't look to see that it really is tag+length+value (but does check // that the array has length 3), just hide the joined TLV triplet in the last element. byte[][] segmentedParameters = { empty, empty, key.EncodedParameters.RawData }; byte[][] algorithmIdentifier = DerEncoder.ConstructSegmentedSequence(algorithmOid, segmentedParameters); byte[][] subjectPublicKey = DerEncoder.SegmentedEncodeBitString(key.EncodedKeyValue.RawData); using (SHA1 hash = SHA1.Create()) { return(hash.ComputeHash( DerEncoder.ConstructSequence( algorithmIdentifier, subjectPublicKey))); } }
public void GetRepositoryCountersignature_WithRepositoryCountersignatureWithInvalidPackageOwners_Throws() { using (var test = new Test(_fixture)) { test.CreateValidAuthorPrimarySignature(); // Generate countersignature test.CounterCmsSigner.SignedAttributes.Add( AttributeUtility.CreateCommitmentTypeIndication(SignatureType.Repository)); var invalidPackageOwnersBytes = DerEncoder.ConstructSequence( (new List <string> { "", " " }).Select(packageOwner => DerEncoder.SegmentedEncodeUtf8String(packageOwner.ToCharArray()))); var invalidPackageOwners = new System.Security.Cryptography.CryptographicAttributeObject( new System.Security.Cryptography.Oid(Oids.NuGetPackageOwners), new System.Security.Cryptography.AsnEncodedDataCollection(new System.Security.Cryptography.AsnEncodedData(Oids.NuGetPackageOwners, invalidPackageOwnersBytes))); test.CounterCmsSigner.SignedAttributes.Add( invalidPackageOwners); test.CounterCmsSigner.SignedAttributes.Add( AttributeUtility.CreateNuGetV3ServiceIndexUrl(new Uri("https://api.nuget.org/v3/index.json"))); test.CounterCmsSigner.SignedAttributes.Add( new Pkcs9SigningTime()); test.CounterCmsSigner.SignedAttributes.Add( AttributeUtility.CreateSigningCertificateV2(test.Certificate, HashAlgorithmName.SHA256)); // Create counter signature test.PrimarySignedCms.SignerInfos[0].ComputeCounterSignature(test.CounterCmsSigner); // Load primary signature var primarySignature = PrimarySignature.Load(test.PrimarySignedCms.Encode()); // Validate countersignature var exception = Assert.Throws <SignatureException>( () => RepositoryCountersignature.GetRepositoryCountersignature(primarySignature)); Assert.Equal(NuGetLogCode.NU3000, exception.Code); Assert.Equal("The nuget-package-owners attribute is invalid.", exception.Message); } }
internal static byte[] X500DistinguishedNameEncode( string stringForm, X500DistinguishedNameFlags flags) { bool reverse = (flags & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed; bool noQuotes = (flags & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes; List <char> dnSeparators; // This rank ordering is based off of testing against the Windows implementation. if ((flags & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons) { // Just semicolon. dnSeparators = s_useSemicolonSeparators; } else if ((flags & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas) { // Just comma dnSeparators = s_useCommaSeparators; } else if ((flags & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines) { // CR or LF. Not "and". Whichever is first was the separator, the later one is trimmed as whitespace. dnSeparators = s_useNewlineSeparators; } else { // Comma or semicolon, but not CR or LF. dnSeparators = s_defaultSeparators; } Debug.Assert(dnSeparators.Count != 0); List <byte[][]> encodedSets = ParseDistinguishedName(stringForm, dnSeparators, noQuotes); if (reverse) { encodedSets.Reverse(); } return(DerEncoder.ConstructSequence(encodedSets)); }
/// <summary> /// Create a CommitmentTypeIndication attribute. /// https://tools.ietf.org/html/rfc5126.html#section-5.11.1 /// </summary> public static CryptographicAttributeObject GetCommitmentTypeIndication(SignatureType type) { // SignatureType -> Oid var valueOid = GetSignatureTypeOid(type); // DER encode the signature type Oid in a sequence. // CommitmentTypeQualifier ::= SEQUENCE { // commitmentTypeIdentifier CommitmentTypeIdentifier, // qualifier ANY DEFINED BY commitmentTypeIdentifier } var commitmentTypeData = DerEncoder.ConstructSequence(new List <byte[][]>() { DerEncoder.SegmentedEncodeOid(valueOid) }); var data = new AsnEncodedData(Oids.CommitmentTypeIndication, commitmentTypeData); // Create an attribute return(new CryptographicAttributeObject( oid: new Oid(Oids.CommitmentTypeIndication), values: new AsnEncodedDataCollection(data))); }
public void GetRepositoryCountersignature_WithRepositoryCountersignatureWithInvalidV3ServiceIndexUrl_Throws() { using (var test = new Test(_fixture)) { test.CreateValidAuthorPrimarySignature(); // Generate countersignature test.CounterCmsSigner.SignedAttributes.Add( AttributeUtility.CreateCommitmentTypeIndication(SignatureType.Repository)); var invalidV3ServiceIndexBytes = DerEncoder.SegmentedEncodeIA5String("notAValidUri".ToCharArray()) .SelectMany(x => x) .ToArray(); var invalidV3ServiceIndex = new System.Security.Cryptography.CryptographicAttributeObject( new System.Security.Cryptography.Oid(Oids.NuGetV3ServiceIndexUrl), new System.Security.Cryptography.AsnEncodedDataCollection(new System.Security.Cryptography.AsnEncodedData(Oids.NuGetV3ServiceIndexUrl, invalidV3ServiceIndexBytes))); test.CounterCmsSigner.SignedAttributes.Add( invalidV3ServiceIndex); test.CounterCmsSigner.SignedAttributes.Add( new Pkcs9SigningTime()); test.CounterCmsSigner.SignedAttributes.Add( AttributeUtility.CreateSigningCertificateV2(test.Certificate, HashAlgorithmName.SHA256)); // Create counter signature test.PrimarySignedCms.SignerInfos[0].ComputeCounterSignature(test.CounterCmsSigner); // Load primary signature var primarySignature = PrimarySignature.Load(test.PrimarySignedCms.Encode()); // Validate countersignature var exception = Assert.Throws <SignatureException>( () => RepositoryCountersignature.GetRepositoryCountersignature(primarySignature)); Assert.Equal(NuGetLogCode.NU3000, exception.Code); Assert.Equal("The nuget-v3-service-index-url attribute is invalid.", exception.Message); } }
public static void CheckUTF8SubstringEncoding(string input, int offset, int length, string expectedHex) { byte[][] encodedString = DerEncoder.SegmentedEncodeUtf8String(input.ToCharArray(), offset, length); Assert.NotNull(encodedString); Assert.Equal(3, encodedString.Length); // Check the tag Assert.NotNull(encodedString[0]); Assert.Equal(1, encodedString[0].Length); Assert.Equal(0x0C, encodedString[0][0]); // Check the length. Since the input cases are all less than 0x7F bytes // the length is only one byte. Assert.NotNull(encodedString[1]); Assert.Equal(1, encodedString[1].Length); Assert.Equal(expectedHex.Length / 2, encodedString[1][0]); // Check the value Assert.Equal(expectedHex.HexToByteArray(), encodedString[2]); // And, full roundtrip Assert.Equal(input.Substring(offset, length), Text.Encoding.UTF8.GetString(encodedString[2])); }
private static byte[][] ParseRdn(Oid tagOid, char[] chars, int valueStart, int valueEnd, bool hadEscapedQuote) { bool ia5String = (tagOid.Value == Oids.EmailAddress); byte[][] encodedOid; try { encodedOid = DerEncoder.SegmentedEncodeOid(tagOid); } catch (CryptographicException e) { throw new CryptographicException(SR.Cryptography_Invalid_X500Name, e); } if (hadEscapedQuote) { char[] value = ExtractValue(chars, valueStart, valueEnd); return(ParseRdn(encodedOid, value, ia5String)); } return(ParseRdn(encodedOid, chars, valueStart, valueEnd, ia5String)); }