/// <summary> /// Initializes the Context /// </summary> private void Initialize(ref ContextSigners signers, ref ContextSignatureNotations signots, ref KeyStore keystore) { IntPtr ptr; var err = libgpgme.gpgme_new(out ptr); gpg_err_code_t errcode = libgpgme.gpgme_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: _ctx_ptr = ptr; signers = new ContextSigners(this); signots = new ContextSignatureNotations(this); keystore = new KeyStore(this); break; case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException("CTX is not a valid pointer.\nBad programmer *spank* *spank*"); case gpg_err_code_t.GPG_ERR_ENOMEM: throw new OutOfMemoryException(); default: throw new GeneralErrorException("An unexpected error occurred during context creation. " + errcode.ToString()); } }
public SignatureResult Sign(GpgmeData plain, GpgmeData sig, SignatureMode mode) { EnsureValid(); if (plain == null) { throw new ArgumentNullException(nameof(plain), "Source data buffer must be supplied."); } if (!(plain.IsValid)) { throw new InvalidDataBufferException("The specified source data buffer is invalid."); } if (sig == null) { throw new ArgumentNullException(nameof(sig), "Destination data buffer must be supplied."); } if (!(sig.IsValid)) { throw new InvalidDataBufferException("The specified destination data buffer is invalid."); } lock (CtxLock) { int err = libgpgme.NativeMethods.gpgme_op_sign( CtxPtr, plain.dataPtr, sig.dataPtr, (gpgme_sig_mode_t)mode); gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_UNUSABLE_SECKEY: throw new InvalidKeyException( "There is one or more invalid signing key(s) in the current context."); case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException( "Either the context, plain text or cipher text pointer is invalid."); default: throw GpgmeError.CreateException(errcode); } IntPtr rst_ptr = libgpgme.NativeMethods.gpgme_op_sign_result(CtxPtr); if (rst_ptr != IntPtr.Zero) { var sig_rst = new SignatureResult(rst_ptr); return(sig_rst); } throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } }
public void Add(string name, string value, SignatureNotationFlags flags) { if (ctx.IsValid) { IntPtr namePtr = IntPtr.Zero; IntPtr valuePtr = IntPtr.Zero; if (name != null) { namePtr = Gpgme.StringToCoTaskMemUTF8(name); } if (value != null) { valuePtr = Gpgme.StringToCoTaskMemUTF8(value); } int err = libgpgme.gpgme_sig_notation_add( ctx.CtxPtr, namePtr, valuePtr, (gpgme_sig_notation_flags_t)flags); if (namePtr != IntPtr.Zero) { Marshal.FreeCoTaskMem(namePtr); namePtr = IntPtr.Zero; } if (valuePtr != IntPtr.Zero) { Marshal.FreeCoTaskMem(valuePtr); valuePtr = IntPtr.Zero; } gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); if (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR) { return; } if (errcode == gpg_err_code_t.GPG_ERR_INV_VALUE) { throw new ArgumentException("NAME and VALUE are in an invalid combination."); } throw new GeneralErrorException("An unexpected error occurred. Error: " + errcode.ToString()); } else { throw new InvalidContextException(); } }
public TrustItem[] GetTrustList(string pattern, int maxlevel) { if (ctx == null || !(ctx.IsValid)) { throw new InvalidContextException(); } if (pattern == null || pattern.Equals(String.Empty)) { throw new ArgumentException("An invalid pattern has been specified."); } IntPtr patternPtr = Gpgme.StringToCoTaskMemUTF8(pattern); List <TrustItem> lst = new List <TrustItem>(); lock (ctx.CtxLock) { int err = libgpgme.gpgme_op_trustlist_start(ctx.CtxPtr, patternPtr, maxlevel); gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); if (errcode != gpg_err_code_t.GPG_ERR_NO_ERROR) { if (patternPtr != IntPtr.Zero) { Marshal.FreeCoTaskMem(patternPtr); patternPtr = IntPtr.Zero; } throw new GeneralErrorException("An unexpected error occurred. Error: " + err.ToString()); } while (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR) { IntPtr itemPtr = IntPtr.Zero; err = libgpgme.gpgme_op_trustlist_next(ctx.CtxPtr, out itemPtr); errcode = libgpgerror.gpg_err_code(err); if (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR) { lst.Add(new TrustItem(itemPtr)); } } // Release context if there are any pending trustlist items err = libgpgme.gpgme_op_trustlist_end(ctx.CtxPtr); if (patternPtr != IntPtr.Zero) { Marshal.FreeCoTaskMem(patternPtr); patternPtr = IntPtr.Zero; } if (errcode != gpg_err_code_t.GPG_ERR_EOF) { throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } } if (lst.Count == 0) { return(new TrustItem[0]); } else { return(lst.ToArray()); } }
public CombinedResult DecryptAndVerify(GpgmeData cipher, GpgmeData plain) { if (IsValid) { if (cipher == null) { throw new ArgumentNullException("Source data buffer must be supplied."); } if (!(cipher.IsValid)) { throw new InvalidDataBufferException("The specified source data buffer is invalid."); } if (plain == null) { throw new ArgumentNullException("Destination data buffer must be supplied."); } if (!(plain.IsValid)) { throw new InvalidDataBufferException("The specified destination data buffer is invalid."); } lock (CtxLock) { #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_decrypt_verify(..) START"); #endif int err = libgpgme.gpgme_op_decrypt_verify( CtxPtr, cipher.dataPtr, plain.dataPtr); #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_decrypt_verify(..) DONE"); #endif gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_NO_DATA: // no encrypted data found - maybe it is only signed. break; case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException("Either the context, cipher text or plain text pointer is invalid."); } DecryptionResult decRst = null; IntPtr rstPtr = libgpgme.gpgme_op_decrypt_result(CtxPtr); if (rstPtr != IntPtr.Zero) { decRst = new DecryptionResult(rstPtr); } switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_DECRYPT_FAILED: if (decRst == null) { throw new DecryptionFailedException("An invalid cipher text has been supplied."); } else { throw new DecryptionFailedException(decRst); } case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE: throw new BadPassphraseException(decRst); default: throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } /* If decryption failed, verification cannot be proceeded */ VerificationResult verRst = null; rstPtr = IntPtr.Zero; rstPtr = libgpgme.gpgme_op_verify_result(CtxPtr); if (rstPtr != IntPtr.Zero) { verRst = new VerificationResult(rstPtr); } GC.KeepAlive(cipher); GC.KeepAlive(plain); return(new CombinedResult(decRst, verRst)); } } else { throw new InvalidContextException(); } }
public DecryptionResult Decrypt(GpgmeData cipher, GpgmeData plain) { if (IsValid) { if (cipher == null) { throw new ArgumentNullException("Source data buffer must be supplied."); } if (!(cipher.IsValid)) { throw new InvalidDataBufferException("The specified source data buffer is invalid."); } if (plain == null) { throw new ArgumentNullException("Destination data buffer must be supplied."); } if (!(plain.IsValid)) { throw new InvalidDataBufferException("The specified destination data buffer is invalid."); } lock (CtxLock) { #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_decrypt(..) START"); #endif int err = libgpgme.gpgme_op_decrypt( CtxPtr, cipher.dataPtr, plain.dataPtr); #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_decrypt(..) DONE"); #endif gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_NO_DATA: throw new NoDataException("The cipher does not contain any data to decrypt or is corrupt."); case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException("Either the context, cipher text or plain text pointer is invalid."); } DecryptionResult decRst = null; IntPtr rstPtr = libgpgme.gpgme_op_decrypt_result(CtxPtr); if (rstPtr != IntPtr.Zero) { decRst = new DecryptionResult(rstPtr); } switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_DECRYPT_FAILED: if (decRst == null) { throw new DecryptionFailedException("An invalid cipher text has been supplied."); } else { throw new DecryptionFailedException(decRst); } case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE: throw new BadPassphraseException(decRst); default: throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } GC.KeepAlive(cipher); GC.KeepAlive(plain); return(decRst);; } } else { throw new InvalidContextException(); } }
public EncryptionResult EncryptAndSign(Key[] recipients, EncryptFlags flags, GpgmeData plain, GpgmeData cipher) { if (IsValid) { if (plain == null) { throw new ArgumentNullException("Source data buffer must be supplied."); } if (!(plain.IsValid)) { throw new InvalidDataBufferException("The specified source data buffer is invalid."); } if (cipher == null) { throw new ArgumentNullException("Destination data buffer must be supplied."); } if (!(cipher.IsValid)) { throw new InvalidDataBufferException("The specified destination data buffer is invalid."); } IntPtr[] recp = Gpgme.KeyArrayToIntPtrArray(recipients); lock (CtxLock) { int err = libgpgme.gpgme_op_encrypt_sign( CtxPtr, recp, (gpgme_encrypt_flags_t)flags, plain.dataPtr, cipher.dataPtr); gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_UNUSABLE_PUBKEY: break; case gpg_err_code_t.GPG_ERR_GENERAL: // Bug? should be GPG_ERR_UNUSABLE_PUBKEY break; case gpg_err_code_t.GPG_ERR_UNUSABLE_SECKEY: throw new InvalidKeyException("There is one or more invalid signing key(s) in the current context."); case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException("Either the context, recipient key array, plain text or cipher text pointer is invalid."); case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE: throw new BadPassphraseException(); default: throw new GeneralErrorException("An unexpected error " + errcode.ToString() + " (" + err.ToString() + ") occurred."); } IntPtr rstPtr = libgpgme.gpgme_op_encrypt_result(CtxPtr); GC.KeepAlive(recp); GC.KeepAlive(recipients); GC.KeepAlive(plain); GC.KeepAlive(cipher); if (rstPtr != IntPtr.Zero) { EncryptionResult encRst = new EncryptionResult(rstPtr); return(encRst); } else { throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } } } else { throw new InvalidContextException(); } }
public void Add(Key signer) { if (ctx.IsValid) { if (signer == null) { throw new ArgumentNullException("A signer key must be supplied."); } if (signer.KeyPtr.Equals(IntPtr.Zero)) { throw new InvalidKeyException("An invalid signer key has been supplied."); } lock (ctx.CtxLock) { int err = libgpgme.gpgme_signers_add(ctx.CtxPtr, signer.KeyPtr); gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); if (errcode != gpg_err_code_t.GPG_ERR_NO_ERROR) { throw new GeneralErrorException("An unexpected error occurred. Error: " + errcode.ToString()); } } } else { throw new InvalidContextException(); } }
public VerificationResult Verify(GpgmeData signature, GpgmeData signedtext, GpgmeData plain) { if (IsValid) { if (signature == null) { throw new ArgumentNullException("A signature data buffer must be supplied."); } if (!(signature.IsValid)) { throw new InvalidDataBufferException("The specified signature data buffer is invalid."); } if ( (signedtext == null || !(signedtext.IsValid)) && (plain == null || !(plain.IsValid)) ) { throw new InvalidDataBufferException("Either the signed text must be provided in order to prove the detached signature, or an empty data buffer to store the plain text result."); } lock (CtxLock) { IntPtr sigPtr = IntPtr.Zero, sigtxtPtr = IntPtr.Zero, plainPtr = IntPtr.Zero; sigPtr = signature.dataPtr; if (signedtext != null && signedtext.IsValid) { sigtxtPtr = signedtext.dataPtr; } if (plain != null && plain.IsValid) { plainPtr = plain.dataPtr; } int err = libgpgme.gpgme_op_verify( CtxPtr, sigPtr, sigtxtPtr, plainPtr); gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_NO_DATA: break; case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidDataBufferException("Either the signature, signed text or plain text data buffer is invalid."); default: throw new GeneralErrorException("Unexpected error occurred. Error: " + errcode.ToString()); } VerificationResult verRst = null; IntPtr rstPtr = IntPtr.Zero; rstPtr = libgpgme.gpgme_op_verify_result(CtxPtr); if (rstPtr != IntPtr.Zero) { verRst = new VerificationResult(rstPtr); if (errcode == gpg_err_code_t.GPG_ERR_NO_DATA) { throw new NoDataException("The signature does not contain any data to verify."); } else { return(verRst); } } else { throw new GeneralErrorException("Could not retrieve verification result."); } } } else { throw new InvalidContextException(); } }
public EncryptionResult Encrypt(Key[] recipients, EncryptFlags flags, GpgmeData plain, GpgmeData cipher) { if (plain == null) { throw new ArgumentNullException("plain", "Source data buffer must be supplied."); } if (!(plain.IsValid)) { throw new InvalidDataBufferException("The specified source data buffer is invalid."); } if (cipher == null) { throw new ArgumentNullException("cipher", "Destination data buffer must be supplied."); } if (!(cipher.IsValid)) { throw new InvalidDataBufferException("The specified destination data buffer is invalid."); } if (!IsValid) { throw new InvalidContextException(); } IntPtr[] recp = Gpgme.KeyArrayToIntPtrArray(recipients); lock (CtxLock) { #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_encrypt(..) START"); #endif int err = libgpgme.gpgme_op_encrypt( CtxPtr, recp, (gpgme_encrypt_flags_t)flags, plain.dataPtr, cipher.dataPtr); #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_encrypt(..) DONE"); #endif gpg_err_code_t errcode = libgpgerror.gpg_err_code(err); switch (errcode) { case gpg_err_code_t.GPG_ERR_NO_ERROR: break; case gpg_err_code_t.GPG_ERR_UNUSABLE_PUBKEY: break; case gpg_err_code_t.GPG_ERR_GENERAL: // Bug? should be GPG_ERR_UNUSABLE_PUBKEY break; case gpg_err_code_t.GPG_ERR_INV_VALUE: throw new InvalidPtrException( "Either the context, recipient key array, plain text or cipher text pointer is invalid."); case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE: throw new BadPassphraseException(); case gpg_err_code_t.GPG_ERR_EBADF: throw new InvalidDataBufferException( "The source (plain) or destination (cipher) data buffer is invalid for encryption."); default: throw new GeneralErrorException("An unexpected error " + errcode.ToString() + " (" + err.ToString(CultureInfo.InvariantCulture) + ") occurred."); } IntPtr rst_ptr = libgpgme.gpgme_op_encrypt_result(CtxPtr); #if (VERBOSE_DEBUG) DebugOutput("gpgme_op_encrypt_result(..) DONE"); #endif GC.KeepAlive(recp); GC.KeepAlive(recipients); GC.KeepAlive(plain); GC.KeepAlive(cipher); if (rst_ptr != IntPtr.Zero) { var enc_rst = new EncryptionResult(rst_ptr); return(enc_rst); } throw new GeneralErrorException("An unexpected error occurred. " + errcode.ToString()); } }