public override DSAParameters ExportParameters(bool includePrivateParameters) { SecKeyPair keys = GetKeys(); if (keys.PublicKey == null || (includePrivateParameters && keys.PrivateKey == null)) { throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); } DSAParameters parameters = new DSAParameters(); DerSequenceReader publicKeyReader = Interop.AppleCrypto.SecKeyExport(keys.PublicKey, exportPrivate: false); publicKeyReader.ReadSubjectPublicKeyInfo(ref parameters); if (includePrivateParameters) { DerSequenceReader privateKeyReader = Interop.AppleCrypto.SecKeyExport(keys.PrivateKey, exportPrivate: true); privateKeyReader.ReadPkcs8Blob(ref parameters); } KeyBlobHelpers.TrimPaddingByte(ref parameters.P); KeyBlobHelpers.TrimPaddingByte(ref parameters.Q); KeyBlobHelpers.PadOrTrim(ref parameters.G, parameters.P.Length); KeyBlobHelpers.PadOrTrim(ref parameters.Y, parameters.P.Length); if (includePrivateParameters) { KeyBlobHelpers.PadOrTrim(ref parameters.X, parameters.Q.Length); } return parameters; }
private byte[] ConvertToApiFormat(byte[] input, int inputOffset, int inputCount) { int size = GetSignatureFieldSize(); try { DerSequenceReader reader = new DerSequenceReader(input, inputOffset, inputCount); byte[] rDer = reader.ReadIntegerBytes(); byte[] sDer = reader.ReadIntegerBytes(); byte[] response = new byte[2 * size]; CopySignatureField(rDer, response, 0, size); CopySignatureField(sDer, response, size, size); return response; } catch (InvalidOperationException e) { throw new CryptographicException(SR.Arg_CryptographyException, e); } }
internal static void ReadPkcs8Blob(this DerSequenceReader reader, ref ECParameters parameters) { // OneAsymmetricKey ::= SEQUENCE { // version Version, // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, // privateKey PrivateKey, // attributes [0] Attributes OPTIONAL, // ..., // [[2: publicKey [1] PublicKey OPTIONAL ]], // ... // } // // PrivateKeyInfo ::= OneAsymmetricKey // // PrivateKey ::= OCTET STRING int version = reader.ReadInteger(); // We understand both version 0 and 1 formats, // which are now known as v1 and v2, respectively. if (version > 1) { throw new CryptographicException(); } { // Ensure we're reading EC Public Key (well, Private, but the OID says Public) DerSequenceReader algorithm = reader.ReadSequence(); string algorithmOid = algorithm.ReadOidAsString(); if (algorithmOid != s_idEcPublicKey.Value) { throw new CryptographicException(); } } byte[] privateKeyBlob = reader.ReadOctetString(); try { // ECPrivateKey{CURVES:IOSet} ::= SEQUENCE { // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), // privateKey OCTET STRING, // parameters [0] Parameters{{IOSet}} OPTIONAL, // publicKey [1] BIT STRING OPTIONAL // } DerSequenceReader keyReader = new DerSequenceReader(privateKeyBlob); version = keyReader.ReadInteger(); // We understand the version 1 format if (version > 1) { throw new CryptographicException(); } parameters.D = keyReader.ReadOctetString(); // Check for context specific 0 const byte ConstructedContextSpecific = DerSequenceReader.ContextSpecificTagFlag | DerSequenceReader.ConstructedFlag; const byte ConstructedContextSpecific0 = (ConstructedContextSpecific | 0); const byte ConstructedContextSpecific1 = (ConstructedContextSpecific | 1); if (keyReader.PeekTag() != ConstructedContextSpecific0) { throw new CryptographicException(); } // Parameters ::= CHOICE { // ecParameters ECParameters, // namedCurve CURVES.&id({ CurveNames}), // implicitlyCA NULL // } DerSequenceReader parametersReader = keyReader.ReadSequence(); if (parametersReader.PeekTag() != (int)DerSequenceReader.DerTag.ObjectIdentifier) { throw new PlatformNotSupportedException(SR.Cryptography_ECC_NamedCurvesOnly); } parameters.Curve = ECCurve.CreateFromValue(parametersReader.ReadOidAsString()); // Check for context specific 1 if (keyReader.PeekTag() != ConstructedContextSpecific1) { throw new CryptographicException(); } keyReader = keyReader.ReadSequence(); byte[] encodedPoint = keyReader.ReadBitString(); ReadEncodedPoint(encodedPoint, ref parameters); // We don't care about the rest of the blob here, but it's expected to not exist. } finally { Array.Clear(privateKeyBlob, 0, privateKeyBlob.Length); } }
internal DerSequenceReader ReadSequence() { // DerSequenceReader wants to read its own tag, so don't EatTag here. CheckTag(DerTag.Sequence, _data, _position); int lengthLength; int contentLength = ScanContentLength(_data, _position + 1, out lengthLength); int totalLength = 1 + lengthLength + contentLength; DerSequenceReader reader = new DerSequenceReader(_data, _position, totalLength); _position += totalLength; return reader; }
/// <summary> /// Convert Der format of (r, s) to Ieee1363 format /// </summary> public static byte[] ConvertDerToIeee1363(byte[] input, int inputOffset, int inputCount, int fieldSizeBits) { int size = BitsToBytes(fieldSizeBits); try { DerSequenceReader reader = new DerSequenceReader(input, inputOffset, inputCount); byte[] rDer = reader.ReadIntegerBytes(); byte[] sDer = reader.ReadIntegerBytes(); byte[] response = new byte[2 * size]; CopySignatureField(rDer, response, 0, size); CopySignatureField(sDer, response, size, size); return response; } catch (InvalidOperationException e) { throw new CryptographicException(SR.Arg_CryptographyException, e); } }