예제 #1
0
        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());
            }
        }
예제 #2
0
        public TrustItem[] GetTrustList(string pattern, int maxlevel)
        {
            if (Context == null ||
                !(Context.IsValid))
            {
                throw new InvalidContextException();
            }

            if (pattern == null || pattern.Equals(String.Empty))
            {
                throw new ArgumentException("An invalid pattern has been specified.");
            }

            IntPtr pattern_ptr = Gpgme.StringToCoTaskMemUTF8(pattern);

            var lst = new List <TrustItem>();

            lock (Context.CtxLock) {
                int            err     = libgpgme.NativeMethods.gpgme_op_trustlist_start(Context.CtxPtr, pattern_ptr, maxlevel);
                gpg_err_code_t errcode = libgpgerror.gpg_err_code(err);

                if (errcode != gpg_err_code_t.GPG_ERR_NO_ERROR)
                {
                    if (pattern_ptr != IntPtr.Zero)
                    {
                        Marshal.FreeCoTaskMem(pattern_ptr);
                    }
                    throw GpgmeError.CreateException(errcode);
                }

                while (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR)
                {
                    IntPtr item_ptr;
                    err     = libgpgme.NativeMethods.gpgme_op_trustlist_next(Context.CtxPtr, out item_ptr);
                    errcode = libgpgerror.gpg_err_code(err);

                    if (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR)
                    {
                        lst.Add(new TrustItem(item_ptr));
                    }
                }
                // Release context if there are any pending trustlist items
                libgpgme.NativeMethods.gpgme_op_trustlist_end(Context.CtxPtr);

                if (pattern_ptr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(pattern_ptr);
                }

                if (errcode != gpg_err_code_t.GPG_ERR_EOF)
                {
                    throw GpgmeError.CreateException(errcode);
                }
            }

            if (lst.Count == 0)
            {
                return(new TrustItem[0]);
            }
            return(lst.ToArray());
        }
예제 #3
0
        public VerificationResult Verify(GpgmeData signature, GpgmeData signedtext, GpgmeData plain)
        {
            EnsureValid();
            if (signature == null)
            {
                throw new ArgumentNullException("signature", "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 sigtxt_ptr = IntPtr.Zero, plain_ptr = IntPtr.Zero;

                IntPtr sig_ptr = signature.dataPtr;
                if (signedtext != null && signedtext.IsValid)
                {
                    sigtxt_ptr = signedtext.dataPtr;
                }
                if (plain != null && plain.IsValid)
                {
                    plain_ptr = plain.dataPtr;
                }

                int err = libgpgme.NativeMethods.gpgme_op_verify(
                    CtxPtr,
                    sig_ptr,
                    sigtxt_ptr,
                    plain_ptr);

                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 GpgmeError.CreateException(errcode);
                }

                IntPtr rst_ptr = libgpgme.NativeMethods.gpgme_op_verify_result(CtxPtr);
                if (rst_ptr != IntPtr.Zero)
                {
                    VerificationResult ver_rst = new VerificationResult(rst_ptr);
                    if (errcode == gpg_err_code_t.GPG_ERR_NO_DATA)
                    {
                        throw new NoDataException("The signature does not contain any data to verify.");
                    }
                    return(ver_rst);
                }
                throw new GeneralErrorException("Could not retrieve verification result.");
            }
        }
예제 #4
0
        public CombinedResult DecryptAndVerify(GpgmeData cipher, GpgmeData plain)
        {
            EnsureValid();
            if (cipher == null)
            {
                throw new ArgumentNullException(nameof(cipher), "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(nameof(plain), "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.NativeMethods.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.");

                default:
                    throw GpgmeError.CreateException(errcode);
                }

                DecryptionResult dec_rst = null;

                IntPtr rst_ptr = libgpgme.NativeMethods.gpgme_op_decrypt_result(CtxPtr);
                if (rst_ptr != IntPtr.Zero)
                {
                    dec_rst = new DecryptionResult(rst_ptr);
                }

                switch (errcode)
                {
                case gpg_err_code_t.GPG_ERR_NO_ERROR:
                    break;

                case gpg_err_code_t.GPG_ERR_DECRYPT_FAILED:
                    if (dec_rst == null)
                    {
                        throw new DecryptionFailedException("An invalid cipher text has been supplied.");
                    }
                    throw new DecryptionFailedException(dec_rst);

                case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE:
                    throw new BadPassphraseException(dec_rst);

                default:
                    throw GpgmeError.CreateException(errcode);
                }

                /* If decryption failed, verification cannot be proceeded */
                VerificationResult ver_rst = null;

                rst_ptr = libgpgme.NativeMethods.gpgme_op_verify_result(CtxPtr);
                if (rst_ptr != IntPtr.Zero)
                {
                    ver_rst = new VerificationResult(rst_ptr);
                }

                GC.KeepAlive(cipher);
                GC.KeepAlive(plain);

                return(new CombinedResult(dec_rst, ver_rst));
            }
        }
예제 #5
0
        public DecryptionResult Decrypt(GpgmeData cipher, GpgmeData plain)
        {
            EnsureValid();
            if (cipher == null)
            {
                throw new ArgumentNullException(nameof(cipher), "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(nameof(plain), "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.NativeMethods.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.");

                default:
                    throw GpgmeError.CreateException(errcode);
                }

                DecryptionResult dec_rst = null;

                IntPtr rst_ptr = libgpgme.NativeMethods.gpgme_op_decrypt_result(CtxPtr);
                if (rst_ptr != IntPtr.Zero)
                {
                    dec_rst = new DecryptionResult(rst_ptr);
                }

                switch (errcode)
                {
                case gpg_err_code_t.GPG_ERR_NO_ERROR:
                    break;

                case gpg_err_code_t.GPG_ERR_DECRYPT_FAILED:
                    if (dec_rst == null)
                    {
                        throw new DecryptionFailedException("An invalid cipher text has been supplied.");
                    }
                    throw new DecryptionFailedException(dec_rst);

                case gpg_err_code_t.GPG_ERR_BAD_PASSPHRASE:
                    throw new BadPassphraseException(dec_rst);

                default:
                    throw GpgmeError.CreateException(errcode);
                }

                GC.KeepAlive(cipher);
                GC.KeepAlive(plain);

                return(dec_rst);
            }
        }
예제 #6
0
        public EncryptionResult EncryptAndSign(Key[] recipients, EncryptFlags flags, GpgmeData plain, GpgmeData cipher)
        {
            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 (cipher == null)
            {
                throw new ArgumentNullException(nameof(cipher), "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.NativeMethods.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.");

                default:
                    throw GpgmeError.CreateException(errcode);
                }
                IntPtr rst_ptr = libgpgme.NativeMethods.gpgme_op_encrypt_result(CtxPtr);

                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());
            }
        }