示例#1
0
        public ImportResult Import(GpgmeData keydata)
        {
            if (Context == null ||
                !(Context.IsValid))
            {
                throw new InvalidContextException();
            }

            if (keydata == null)
            {
                throw new ArgumentNullException("An invalid data buffer has been specified.",
                                                new InvalidDataBufferException());
            }

            if (!(keydata.IsValid))
            {
                throw new InvalidDataBufferException();
            }

            lock (Context.CtxLock) {
                GpgmeError.Check(libgpgme.NativeMethods.gpgme_op_import(Context.CtxPtr, keydata.dataPtr));
                IntPtr result = libgpgme.NativeMethods.gpgme_op_import_result(Context.CtxPtr);
                return(new ImportResult(result));
            }
        }
        public void Export(string[] pattern, GpgmeData keydata)
        {
            if (ctx == null ||
                !(ctx.IsValid))
            {
                throw new InvalidContextException();
            }

            if (keydata == null)
            {
                throw new ArgumentNullException("Invalid data buffer",
                                                new InvalidDataBufferException());
            }

            if (!(keydata.IsValid))
            {
                throw new InvalidDataBufferException();
            }

            IntPtr[] parray = null;
            if (pattern != null)
            {
                parray = Gpgme.StringToCoTaskMemUTF8(pattern);
            }

            int  err;
            uint reserved = 0;

            lock (ctx.CtxLock)
            {
                if (parray != null)
                {
                    err = libgpgme.gpgme_op_export_ext(
                        ctx.CtxPtr,
                        parray,
                        reserved,
                        keydata.dataPtr);
                }
                else
                {
                    err = libgpgme.gpgme_op_export(
                        ctx.CtxPtr,
                        IntPtr.Zero,
                        reserved,
                        keydata.dataPtr);
                }
            }

            GC.KeepAlive(keydata);

            // Free memory
            Gpgme.FreeStringArray(parray);

            gpg_err_code_t errcode = libgpgerror.gpg_err_code(err);

            if (errcode != gpg_err_code_t.GPG_ERR_NO_ERROR)
            {
                throw new KeyExportException("Error " + errcode, err);
            }
        }
        public ImportResult Import(GpgmeData keydata)
        {
            if (ctx == null ||
                !(ctx.IsValid))
            {
                throw new InvalidContextException();
            }

            if (keydata == null)
            {
                throw new ArgumentNullException("An invalid data buffer has been specified.",
                                                new InvalidDataBufferException());
            }

            if (!(keydata.IsValid))
            {
                throw new InvalidDataBufferException();
            }

            lock (ctx.CtxLock)
            {
                int            err     = libgpgme.gpgme_op_import(ctx.CtxPtr, keydata.dataPtr);
                gpg_err_code_t errcode = libgpgerror.gpg_err_code(err);

                if (errcode != gpg_err_code_t.GPG_ERR_NO_ERROR)
                {
                    throw new KeyImportException("Error " + errcode, err);
                }

                IntPtr result = libgpgme.gpgme_op_import_result(ctx.CtxPtr);
                return(new ImportResult(result));
            }
        }
示例#4
0
        public void Export(string[] pattern, GpgmeData keydata, ExportMode?mode = null)
        {
            if (Context == null ||
                !(Context.IsValid))
            {
                throw new InvalidContextException();
            }

            if (keydata == null)
            {
                throw new ArgumentNullException("Invalid data buffer",
                                                new InvalidDataBufferException());
            }

            if (!(keydata.IsValid))
            {
                throw new InvalidDataBufferException();
            }

            IntPtr[] parray = null;
            if (pattern != null)
            {
                parray = Gpgme.StringToCoTaskMemUTF8(pattern);
            }

            int err;
            var apiMode = mode == null ? 0 : (uint)mode;

            lock (Context.CtxLock) {
                if (parray != null)
                {
                    err = libgpgme.NativeMethods.gpgme_op_export_ext(
                        Context.CtxPtr,
                        parray,
                        apiMode,
                        keydata.dataPtr);
                }
                else
                {
                    err = libgpgme.NativeMethods.gpgme_op_export(
                        Context.CtxPtr,
                        IntPtr.Zero,
                        apiMode,
                        keydata.dataPtr);
                }
            }

            GC.KeepAlive(keydata);

            // Free memory
            Gpgme.FreeStringArray(parray);

            GpgmeError.Check(err);
        }
示例#5
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());
            }
        }
        protected int StartEdit(Context ctx, IntPtr handle, GpgmeData data)
        {
            if (KeyPtr == IntPtr.Zero)
            {
                throw new InvalidKeyException();
            }

            if (ctx == null || !(ctx.IsValid))
            {
                throw new InvalidContextException();
            }

            if (data == null || !(data.IsValid))
            {
                throw new InvalidDataBufferException();
            }

            lock (editlock)
            {
                LastCallbackException = null;

                // set the instance's _edit_cb() method as callback function for libgpgme
                _instance_key_edit_callback = new gpgme_edit_cb_t(_edit_cb);

                // start key editing
                int err = libgpgme.gpgme_op_edit(
                    ctx.CtxPtr,
                    KeyPtr,
                    _instance_key_edit_callback,
                    handle,
                    data.dataPtr);

                GC.KeepAlive(_instance_key_edit_callback);

                if (LastCallbackException != null)
                {
                    throw LastCallbackException;
                }

                return(err);
            }
        }
 public void Export(string pattern, GpgmeData keydata)
 {
     Export(new string[] { pattern }, keydata);
 }
        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 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();
            }
        }
示例#12
0
        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());
            }
        }
示例#13
0
        protected int StartEdit(Context ctx, IntPtr handle, GpgmeData data)
        {
            if (KeyPtr == IntPtr.Zero)
                throw new InvalidKeyException();

            if (ctx == null || !(ctx.IsValid))
                throw new InvalidContextException();

            if (data == null || !(data.IsValid))
                throw new InvalidDataBufferException();

            lock (editlock)
            {
                LastCallbackException = null;

                // set the instance's _edit_cb() method as callback function for libgpgme
                _instance_key_edit_callback = new gpgme_edit_cb_t(_edit_cb);

                // start key editing
                int err = libgpgme.gpgme_op_edit(
                    ctx.CtxPtr,
                    KeyPtr,
                    _instance_key_edit_callback,
                    handle,
                    data.dataPtr);

                GC.KeepAlive(_instance_key_edit_callback);

                if (LastCallbackException != null)
                    throw LastCallbackException;

                return err;
            }
        }
示例#14
0
 public void Export(string pattern, GpgmeData keydata, ExportMode?mode = null)
 {
     Export(new[] { pattern }, keydata, mode);
 }
示例#15
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.");
            }
        }