/// <summary> /// Begins PKCS#12 encoding. /// </summary> public void Begin() { this.der = new DerEncoder(); this.macSalt = GetRandomBytes(8); this.der.StartSEQUENCE(); // PFX (RFC 7292, §4) this.der.INTEGER(3); // version }
/// <summary> /// Exports the public key using DER. /// </summary> /// <param name="Output">Encoded output.</param> public override void ExportPublicKey(DerEncoder Output) { RSAParameters Parameters = this.rsa.ExportParameters(false); Output.StartSEQUENCE(); Output.INTEGER(Parameters.Modulus, false); Output.INTEGER(Parameters.Exponent, false); Output.EndSEQUENCE(); }
private void Push() { if (this.stack is null) { this.stack = new LinkedList <DerEncoder>(); } this.stack.AddLast(this.der); this.der = new DerEncoder(); }
private static void EncodePrivateKeyInfo(DerEncoder Der, SignatureAlgorithm Algorithm) { Der.StartSEQUENCE(); // PrivateKeyInfo Der.INTEGER(0); // version Der.OBJECT_IDENTIFIER(Algorithm.PkiAlgorithmOID); // privateKeyAlgorithm Der.StartOCTET_STRING(); Algorithm.ExportPrivateKey(Der); // privateKey Der.EndOCTET_STRING(); Der.NULL(); // Attributes Der.EndSEQUENCE(); // End of PrivateKeyInfo }
private byte[] Pop() { if (this.stack is null || this.stack.Last is null) { throw new InvalidOperationException("Stack empty."); } byte[] Result = this.der.ToArray(); this.der = this.stack.Last.Value; this.stack.RemoveLast(); return(Result); }
/// <summary> /// Exports the private key using DER. /// </summary> /// <param name="Output">Encoded output.</param> public override void ExportPrivateKey(DerEncoder Output) { RSAParameters Parameters = this.rsa.ExportParameters(true); Output.StartSEQUENCE(); Output.INTEGER(0); // Version Output.INTEGER(Parameters.Modulus, false); Output.INTEGER(Parameters.Exponent, false); Output.INTEGER(Parameters.D, false); Output.INTEGER(Parameters.P, false); Output.INTEGER(Parameters.Q, false); Output.INTEGER(Parameters.DP, false); Output.INTEGER(Parameters.DQ, false); Output.INTEGER(Parameters.InverseQ, false); Output.EndSEQUENCE(); }
/// <summary> /// Encodes a ShroudedKeyBag (§4.2.2 RFC 7292, §6, RFC 5208) /// </summary> /// <param name="Encryption">Encryption algorithm.</param> /// <param name="Algorithm">Algorithm containing private key.</param> public void ShroudedKeyBag(PasswordEncryption Encryption, SignatureAlgorithm Algorithm) { this.StartSafeBag(bagTypes + ".2"); DerEncoder Key = new DerEncoder(); EncodePrivateKeyInfo(Key, Algorithm); byte[] PrivateKey = Key.ToArray(); this.der.StartSEQUENCE(); // EncryptedPrivateKeyInfo Encryption.EncodePkcs5AlgorithmIdentifier(this.der); this.der.OCTET_STRING(Encryption.Encrypt(PrivateKey)); this.der.NULL(); // Attributes this.der.EndSEQUENCE(); // End of EncryptedPrivateKeyInfo this.EndSafeBag(); // TODO: attributes }
private void EncodeIfDefined(DerEncoder DER, string OID, string Value) { if (Value != null) { DER.StartSET(); DER.StartSEQUENCE(); DER.OBJECT_IDENTIFIER(OID); if (DerEncoder.IsPrintable(Value)) { DER.PRINTABLE_STRING(Value); } else { DER.IA5_STRING(Value); } DER.EndSEQUENCE(); DER.EndSET(); } }
/// <summary> /// Ends PKCS#12 encoding and returns the encoded result. /// </summary> /// <returns>PKCS#12 encoded data.</returns> public byte[] End() { this.AssertBegun(); if (this.stack != null && this.stack.First != null) { throw new InvalidOperationException("Stack not empty."); } this.der.StartSEQUENCE(); // macData:MacData this.der.StartSEQUENCE(); // mac:DigestInfo // TODO this.der.EndSEQUENCE(); // End of mac:DigestInfo this.der.OCTET_STRING(this.macSalt); // macSalt this.der.INTEGER(2048); // iterations this.der.EndSEQUENCE(); // End of macData:MacData this.der.EndSEQUENCE(); byte[] Result = this.der.ToArray(); this.der = null; return(Result); }
/// <summary> /// Building a Certificate Signing Request (CSR) in accordance with RFC 2986 /// </summary> /// <returns>CSR</returns> public byte[] BuildCSR() { DerEncoder DER = new DerEncoder(); DER.StartSEQUENCE(); // CertificationRequestInfo DER.INTEGER(0); // Version DER.StartSEQUENCE(); // subject this.EncodeIfDefined(DER, "2.5.4.3", this.commonName); this.EncodeIfDefined(DER, "2.5.4.4", this.surname); this.EncodeIfDefined(DER, "2.5.4.5", this.serialNumber); this.EncodeIfDefined(DER, "2.5.4.6", this.country); this.EncodeIfDefined(DER, "2.5.4.7", this.locality); this.EncodeIfDefined(DER, "2.5.4.8", this.stateOrProvince); this.EncodeIfDefined(DER, "2.5.4.9", this.streetAddress); this.EncodeIfDefined(DER, "2.5.4.10", this.organization); this.EncodeIfDefined(DER, "2.5.4.11", this.organizationalUnit); this.EncodeIfDefined(DER, "2.5.4.12", this.title); this.EncodeIfDefined(DER, "2.5.4.13", this.description); this.EncodeIfDefined(DER, "2.5.4.16", this.postalAddress); this.EncodeIfDefined(DER, "2.5.4.17", this.postalCode); this.EncodeIfDefined(DER, "2.5.4.18", this.postOfficeBox); this.EncodeIfDefined(DER, "2.5.4.19", this.physicalDeliveryOfficeName); this.EncodeIfDefined(DER, "2.5.4.20", this.telephoneNumber); this.EncodeIfDefined(DER, "2.5.4.26", this.registeredAddress); this.EncodeIfDefined(DER, "2.5.4.29", this.presentationAddress); this.EncodeIfDefined(DER, "2.5.4.41", this.name); this.EncodeIfDefined(DER, "2.5.4.42", this.givenName); this.EncodeIfDefined(DER, "2.5.4.43", this.initials); this.EncodeIfDefined(DER, "2.5.4.49", this.distinguishedName); this.EncodeIfDefined(DER, "2.5.4.51", this.houseIdentifier); this.EncodeIfDefined(DER, "1.2.840.113549.1.9.1", this.emailAddress); DER.EndSEQUENCE(); // end of subject DER.StartSEQUENCE(); // subjectPKInfo DER.StartSEQUENCE(); // algorithm DER.OBJECT_IDENTIFIER(this.signatureAlgorithm.PkiAlgorithmOID); DER.NULL(); // No parameters DER.EndSEQUENCE(); // end of algorithm DER.StartBITSTRING(); // subjectPublicKey this.signatureAlgorithm.ExportPublicKey(DER); DER.EndBITSTRING(); // end of subjectPublicKey DER.EndSEQUENCE(); // end of subjectPKInfo DER.StartContent(Asn1TypeClass.ContextSpecific); // attributes if (this.subjectAlternativeNames != null && this.subjectAlternativeNames.Length > 0) { DER.StartSEQUENCE(); DER.OBJECT_IDENTIFIER("1.2.840.113549.1.9.14"); // extensionRequest DER.StartSET(); DER.StartSEQUENCE(); DER.StartSEQUENCE(); DER.OBJECT_IDENTIFIER("2.5.29.17"); DER.StartOCTET_STRING(); DER.StartSEQUENCE(); foreach (string s in this.subjectAlternativeNames) { int Pos = DER.Position; DER.IA5_STRING(s); DER[Pos] = 0x82; // Encoded as Context-specific INTEGER... } DER.EndSEQUENCE(); DER.EndOCTET_STRING(); DER.EndSEQUENCE(); DER.EndSEQUENCE(); DER.EndSET(); DER.EndSEQUENCE(); } DER.EndContent(Asn1TypeClass.ContextSpecific); // end of attributes DER.EndSEQUENCE(); // end of CertificationRequestInfo byte[] CertificationRequestInfo = DER.ToArray(); DER.Clear(); DER.StartSEQUENCE(); // CertificationRequest DER.Raw(CertificationRequestInfo); DER.StartSEQUENCE(); // signatureAlgorithm DER.OBJECT_IDENTIFIER(this.signatureAlgorithm.HashAlgorithmOID); DER.NULL(); // parameters DER.EndSEQUENCE(); // End of signatureAlgorithm DER.BITSTRING(this.signatureAlgorithm.Sign(CertificationRequestInfo)); // signature DER.EndSEQUENCE(); // end of CertificationRequest return(DER.ToArray()); }
/// <summary> /// Exports the private key using DER. /// </summary> /// <param name="Output">Encoded output.</param> public abstract void ExportPrivateKey(DerEncoder Output);
/// <summary> /// Exports the public key using DER. /// </summary> /// <param name="Output">Encoded output.</param> public abstract void ExportPublicKey(DerEncoder Output);