public X509Certificate2 GetCertificateAsX509Certificate2() { if (this._disposed) { throw new ObjectDisposedException(this.GetType().FullName); } return(CertUtils.ToDotNetObject(GetSigningCertificate())); }
/// <summary> /// Main method specifying where program execution is to begin /// </summary> /// <param name="args">Command line arguments passed to the program</param> static void Main(string[] args) { try { // Parse command line arguments string pkcs11Library = null; int listTokens = 0; int listObjects = 0; int sign = 0; string tokenSerial = null; string tokenLabel = null; string pin = null; string keyLabel = null; string keyId = null; string inputPdf = null; string outputPdf = null; string hashAlg = null; string certsDir = null; if (args.Length == 0) { ExitWithHelp(null); } int i = 0; while (i < args.Length) { switch (args[i]) { case _argPkcs11Library: pkcs11Library = args[++i]; break; case _argListTokens: listTokens = 1; break; case _argListObjects: listObjects = 1; break; case _argSign: sign = 1; break; case _argTokenSerial: tokenSerial = args[++i]; break; case _argTokenLabel: tokenLabel = args[++i]; break; case _argPin: pin = args[++i]; break; case _argKeyLabel: keyLabel = args[++i]; break; case _argKeyId: keyId = args[++i]; break; case _argInputPdf: inputPdf = args[++i]; break; case _argOutputPdf: outputPdf = args[++i]; break; case _argHashAlg: hashAlg = args[++i]; break; case _argCertsDir: certsDir = args[++i]; break; default: ExitWithHelp("Invalid argument: " + args[i]); break; } i++; } // Validate operation modes if (listTokens + listObjects + sign != 1) { ExitWithHelp(string.Format("Argument \"{0}\", \"{1}\" or \"{2}\" has to be specified", _argListTokens, _argListObjects, _argSign)); } // Handle "--list-tokens" operation mode if (listTokens == 1) { // Validate command line arguments if (string.IsNullOrEmpty(pkcs11Library)) { ExitWithHelp("Required argument: " + _argPkcs11Library); } if (!string.IsNullOrEmpty(tokenSerial)) { ExitWithHelp("Unexpected argument: " + _argTokenSerial); } if (!string.IsNullOrEmpty(tokenLabel)) { ExitWithHelp("Unexpected argument: " + _argTokenLabel); } if (!string.IsNullOrEmpty(pin)) { ExitWithHelp("Unexpected argument: " + _argPin); } if (!string.IsNullOrEmpty(keyLabel)) { ExitWithHelp("Unexpected argument: " + _argKeyLabel); } if (!string.IsNullOrEmpty(keyId)) { ExitWithHelp("Unexpected argument: " + _argKeyId); } if (!string.IsNullOrEmpty(inputPdf)) { ExitWithHelp("Unexpected argument: " + _argInputPdf); } if (!string.IsNullOrEmpty(outputPdf)) { ExitWithHelp("Unexpected argument: " + _argOutputPdf); } if (!string.IsNullOrEmpty(hashAlg)) { ExitWithHelp("Unexpected argument: " + _argHashAlg); } if (!string.IsNullOrEmpty(certsDir)) { ExitWithHelp("Unexpected argument: " + _argCertsDir); } // Perform requested operation using (Pkcs11Explorer pkcs11Explorer = new Pkcs11Explorer(pkcs11Library)) { Console.WriteLine("Listing available tokens"); int j = 1; List <Token> tokens = pkcs11Explorer.GetTokens(); foreach (Token token in tokens) { Console.WriteLine(); Console.WriteLine("Token no." + j); Console.WriteLine(" Manufacturer: " + token.ManufacturerId); Console.WriteLine(" Model: " + token.Model); Console.WriteLine(" Serial number: " + token.SerialNumber); Console.WriteLine(" Label: " + token.Label); j++; } } } // Handle "--list-objects" operation mode if (listObjects == 1) { // Validate command line arguments if (string.IsNullOrEmpty(pkcs11Library)) { ExitWithHelp("Required argument: " + _argPkcs11Library); } if (string.IsNullOrEmpty(tokenSerial) && string.IsNullOrEmpty(tokenLabel)) { ExitWithHelp("Required argument: " + _argTokenSerial + " and/or " + _argTokenLabel); } if (string.IsNullOrEmpty(pin)) { ExitWithHelp("Required argument: " + _argPin); } if (!string.IsNullOrEmpty(keyLabel)) { ExitWithHelp("Unexpected argument: " + _argKeyLabel); } if (!string.IsNullOrEmpty(keyId)) { ExitWithHelp("Unexpected argument: " + _argKeyId); } if (!string.IsNullOrEmpty(inputPdf)) { ExitWithHelp("Unexpected argument: " + _argInputPdf); } if (!string.IsNullOrEmpty(outputPdf)) { ExitWithHelp("Unexpected argument: " + _argOutputPdf); } if (!string.IsNullOrEmpty(hashAlg)) { ExitWithHelp("Unexpected argument: " + _argHashAlg); } if (!string.IsNullOrEmpty(certsDir)) { ExitWithHelp("Unexpected argument: " + _argCertsDir); } // Perform requested operation using (Pkcs11Explorer pkcs11Explorer = new Pkcs11Explorer(pkcs11Library)) { Console.WriteLine(string.Format("Listing objects available on token with serial \"{0}\" and label \"{1}\"", tokenSerial, tokenLabel)); // Find requested token Token foundToken = null; List <Token> tokens = pkcs11Explorer.GetTokens(); foreach (Token token in tokens) { if (!string.IsNullOrEmpty(tokenLabel)) { if (0 != String.Compare(tokenLabel, token.Label, StringComparison.InvariantCultureIgnoreCase)) { continue; } } if (!string.IsNullOrEmpty(tokenSerial)) { if (0 != String.Compare(tokenSerial, token.SerialNumber, StringComparison.InvariantCultureIgnoreCase)) { continue; } } foundToken = token; break; } if (foundToken == null) { throw new TokenNotFoundException(string.Format("Token with serial \"{0}\" and label \"{1}\" was not found", tokenSerial, tokenLabel)); } // Get private keys and certificates stored in requested token List <PrivateKey> privateKeys = null; List <Certificate> certificates = null; pkcs11Explorer.GetTokenObjects(foundToken, true, pin, out privateKeys, out certificates); // Print private keys int j = 1; foreach (PrivateKey privateKey in privateKeys) { Console.WriteLine(); Console.WriteLine("Private key #" + j); int[] matchingCertIds = GetMatchingCertIds(privateKey, certificates); Console.WriteLine(" Matching certs: " + PrintMatchingIds(matchingCertIds)); Console.WriteLine(" ID (CKA_ID): " + privateKey.Id); Console.WriteLine(" Label (CKA_LABEL): " + privateKey.Label); // Print public part of RSA key if ((privateKey.PublicKey != null) && (privateKey.PublicKey is RsaKeyParameters)) { RsaKeyParameters rsa = privateKey.PublicKey as RsaKeyParameters; Console.WriteLine(" RSA exponent: " + ConvertUtils.BytesToHexString(rsa.Exponent.ToByteArrayUnsigned())); Console.WriteLine(" RSA public modulus: " + ConvertUtils.BytesToHexString(rsa.Modulus.ToByteArrayUnsigned())); } j++; } // Print certificates int k = 1; foreach (Certificate certificate in certificates) { Console.WriteLine(); Console.WriteLine("Certificate #" + k); int[] matchingKeyIds = GetMatchingKeyIds(certificate, privateKeys); Console.WriteLine(" Matching keys: " + PrintMatchingIds(matchingKeyIds)); X509Certificate2 x509Cert = CertUtils.ToDotNetObject(certificate.Data); Console.WriteLine(" ID (CKA_ID): " + certificate.Id); Console.WriteLine(" Label (CKA_LABEL): " + certificate.Label); Console.WriteLine(" Serial number: " + x509Cert.SerialNumber); Console.WriteLine(" Subject DN: " + x509Cert.Subject); Console.WriteLine(" Issuer DN: " + x509Cert.Issuer); Console.WriteLine(" Not before: " + x509Cert.NotBefore); Console.WriteLine(" Not after: " + x509Cert.NotAfter); // Print certified public RSA key if ((certificate.PublicKey != null) && (certificate.PublicKey is RsaKeyParameters)) { RsaKeyParameters rsa = certificate.PublicKey as RsaKeyParameters; Console.WriteLine(" RSA exponent: " + ConvertUtils.BytesToHexString(rsa.Exponent.ToByteArrayUnsigned())); Console.WriteLine(" RSA public modulus: " + ConvertUtils.BytesToHexString(rsa.Modulus.ToByteArrayUnsigned())); } k++; } } } // Handle "--sign" operation mode if (sign == 1) { // Use SHA256 as default hashing algorithm HashAlgorithm hashAlgorithm = HashAlgorithm.SHA256; // Validate command line arguments (_argHashAlg and _argCertsDir are optional) if (string.IsNullOrEmpty(pkcs11Library)) { ExitWithHelp("Required argument: " + _argPkcs11Library); } if (string.IsNullOrEmpty(tokenSerial) && string.IsNullOrEmpty(tokenLabel)) { ExitWithHelp("Required argument: " + _argTokenSerial + " and/or " + _argTokenLabel); } if (string.IsNullOrEmpty(pin)) { ExitWithHelp("Required argument: " + _argPin); } if (string.IsNullOrEmpty(keyLabel) && string.IsNullOrEmpty(keyId)) { ExitWithHelp("Required argument: " + _argKeyLabel + " and/or " + _argKeyId); } if (string.IsNullOrEmpty(inputPdf)) { ExitWithHelp("Required argument: " + _argInputPdf); } if (string.IsNullOrEmpty(outputPdf)) { ExitWithHelp("Required argument: " + _argOutputPdf); } if (!string.IsNullOrEmpty(hashAlg)) { hashAlgorithm = (HashAlgorithm)Enum.Parse(typeof(HashAlgorithm), hashAlg); } // Perform requested operation using (Pkcs11RsaSignature pkcs11RsaSignature = new Pkcs11RsaSignature(pkcs11Library, tokenSerial, tokenLabel, pin, keyLabel, keyId, hashAlgorithm)) { Console.WriteLine(string.Format("Signing PDF document \"{0}\" using private key with ID \"{1}\" and label \"{2}\" stored on token with serial \"{3}\" and label \"{4}\"", inputPdf, keyId, keyLabel, tokenSerial, tokenLabel)); // Read signing certificate from the token byte[] signingCertificate = pkcs11RsaSignature.GetSigningCertificate(); // Read all certificates stored on the token List <byte[]> otherCertificates = pkcs11RsaSignature.GetAllCertificates(); // Read additional certificates from directory if (!string.IsNullOrEmpty(certsDir)) { foreach (string file in Directory.GetFiles(certsDir)) { otherCertificates.Add(File.ReadAllBytes(file)); } } // Build certification path for the signing certificate ICollection <Org.BouncyCastle.X509.X509Certificate> certPath = CertUtils.BuildCertPath(signingCertificate, otherCertificates); // Read unsigned PDF document using (PdfReader pdfReader = new PdfReader(inputPdf)) { // Create output stream for signed PDF document using (FileStream outputStream = new FileStream(outputPdf, FileMode.Create)) { // Create PdfStamper that applies extra content to the PDF document using (PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, outputStream, '\0', Path.GetTempFileName(), true)) { // Sign PDF document MakeSignature.SignDetached(pdfStamper.SignatureAppearance, pkcs11RsaSignature, certPath, null, null, null, 0, CryptoStandard.CADES); } } } } } } catch (Exception ex) { Console.WriteLine(@"Operation error: " + ex.GetType() + " - " + ex.Message); Console.WriteLine(ex.StackTrace); Environment.Exit(_exitError); } Environment.Exit(_exitSuccess); }