├── .gitignore ├── COPYRIGHT ├── INSTALL-NOTE.TXT ├── LICENSE ├── README ├── RELEASE-NOTE.TXT ├── SOURCES ├── bin │ ├── cipher_key_regist.bat │ ├── cipher_key_regist.ps1 │ ├── cipher_key_regist.sh │ ├── cipher_setup.bat │ ├── cipher_setup.ps1 │ └── cipher_setup.sh ├── data_encryption │ ├── 10 │ ├── 95 │ ├── 96 │ ├── makedencryption.sh │ ├── msvc_tools │ │ ├── Mkvcbuild.pm.10.diff │ │ ├── Mkvcbuild.pm.95.diff │ │ ├── Mkvcbuild.pm.96.diff │ │ ├── config.pl │ │ └── win32ver.rc │ ├── pgcrypto-aes-ni │ │ ├── openssl.c │ │ └── pgp-encrypt.patch │ ├── tdeforpg │ │ ├── Makefile.in │ │ ├── data_encryption.c │ │ └── data_encryption.h │ ├── win_build.bat │ └── win_fe_build_procedure.txt ├── lib │ ├── init │ │ ├── cipher_definition.sql │ │ ├── cipher_key_function.sql │ │ ├── common_session_create.sql │ │ ├── common_session_dummy_create.sql │ │ └── pgtde_parallel_safe_setting.sql │ └── upgrade │ │ ├── installed_list_fe_V1_0_0_0.txt │ │ ├── installed_list_fe_V1_1_0_0.txt │ │ ├── installed_list_fe_V1_1_1_0.txt │ │ ├── installed_list_fe_V1_1_1_1.txt │ │ ├── installed_list_fe_V1_1_2_0.txt │ │ └── installed_list_fe_V1_2_1_0.txt ├── sys │ └── .gitkeep └── test │ ├── README │ └── t │ ├── DDL │ ├── alter_table.pg │ ├── create_index.pg │ ├── create_table.pg │ └── reindex.pg │ ├── cast │ └── cast.pg │ ├── encbytea │ ├── aggregation │ │ └── aggregate_bytea.pg │ ├── cmp │ │ └── cmp_encbytea.pg │ ├── copy │ │ └── copy_binary_bytea.pg │ ├── function │ │ └── encbytea_fucntion.pg │ ├── parameter │ │ └── encbytea_enable_off.pg │ ├── reencryption │ │ └── encbytea_reset.pg │ └── session │ │ ├── encbytea_beginssession.pg │ │ └── encbytea_beginssession_etc.pg │ └── enctext │ ├── aggregation │ └── aggregate_text.pg │ ├── cmp │ ├── cmp_enctext.pg │ └── cmp_enctext_with_plaintype.pg │ ├── copy │ └── copy_binary_text.pg │ ├── function │ ├── enctext_fucntion.pg │ ├── pattern_matching.pg │ └── text_search.pg │ ├── parameter │ └── encbytea_enable_off.pg │ ├── reencryption │ └── enctext_reset.pg │ └── session │ ├── enctext_beginssession.pg │ └── enctext_beginssession_etc.pg ├── UPGRADE-GUIDE.TXT └── docs ├── images ├── cipher_setup_FE.png ├── install1_start_FE.png ├── install4_finish_FE.png └── pgtde_regist_FE.png └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Transparent Data Encryption for PostgreSQL Free Edition 2 | 3 | Copyright (c) 2015-2018, NEC Corporation 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | Portions are: 19 | Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 20 | 21 | Portions Copyright (c) 1994, The Regents of the University of California 22 | 23 | Permission to use, copy, modify, and distribute this software and its 24 | documentation for any purpose, without fee, and without a written agreement 25 | is hereby granted, provided that the above copyright notice and this 26 | paragraph and the following two paragraphs appear in all copies. 27 | 28 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR 29 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING 30 | LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 31 | DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | 34 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 35 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 36 | AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 37 | ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO 38 | PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 39 | -------------------------------------------------------------------------------- /INSTALL-NOTE.TXT: -------------------------------------------------------------------------------- 1 | Installation Notes 2 | ================== 3 | Installation instructions for Transparent Data Encryption for PostgreSQL Free Edition 4 | 5 | Requirements 6 | ============ 7 | 1. PostgreSQL Source Code 8 | # It is not required, if you installed tdeforpg from RPM. 9 | 2. PostgreSQL with psql installed 10 | 11 | Installation and Configuration 12 | ============================== 13 | 1. Setting environment variables 14 | $ export PGSRC = #path of PostgreSQL source code 15 | $ export PGHOME = #path of PostgreSQL installed 16 | $ export TDEHOME = #path of tdeforpg downloaded 17 | 18 | 2. Install pgcrypto from source code 19 | # If you have already installed pgcrypto, you can skip this section. 20 | $ cd $PGSRC/contrib/pgcrypto 21 | $ gmake 22 | $ gmake install 23 | $ pg_ctl start 24 | $ psql << EOF 25 | > CREATE EXTENSION pgcrypto; 26 | > EOF 27 | 28 | 3. Building pgTDE 29 | # If you installed tdeforpg from RPM, please skip this section. 30 | $ sudo ln -s $PGHOME/lib/pgcrypto.so /usr/lib64/libpgcrypto.so 31 | $ cd $PGSRC 32 | $ ./configure 33 | $ cd $TDEHOME/SOURCES/data_encryption 34 | $ sh makedencryption.sh $PGSRC 35 | # is version of PostgreSQL without dot (93 or 94) 36 | 37 | 38 | 4. install pgTDE to PostgreSQL 39 | $ sudo ln -s $TDEHOME/SOURCES/data_encryption//data_encryption.so. /usr/lib64/data_encryption.so 40 | $ vim $PGDATA/postgresql.conf # add shared_preload_libraries to postgresql.conf 41 | shared_preload_libraries='/usr/lib64/data_encryption.so' 42 | $ pg_ctl restart 43 | $ cd $TDEHOME/SOURCES 44 | $ sh bin/cipher_setup.sh $PGHOME 45 | Transparent data encryption feature setup script 46 | Please select from the setup menu below 47 | Transparent data encryption feature setup menu 48 | 1: activate the transparent data encryption feature 49 | 2: inactivate the transparent data encryption feature 50 | select menu [1 - 2] > 1 51 | Please enter database server port to connect : 52 | Please enter database user name to connect : 53 | Please enter password for authentication : 54 | Please enter database name to connect : 55 | 56 | 5. AES-NI support 57 | pgcrypto from PostgreSQL 10 support AES-NI. 58 | You can use Windows installer, Linux rpm or build your PostgreSQL 59 | with --with-openssl option. 60 | 61 | In PostgreSQL 9.5 or 9.6, if you want to use AES-NI supported pgcrypto, 62 | Please replace ${PGHOME}/lib/pgcrypto.so (pgcrypto.dll in Windows) 63 | with the AES-NI supported binary below, 64 | 65 | Linux: ${TDEHOME}/SOURCES/data_encryption//libpgcrypto.so. 66 | Windows: ${TDEHOME}\lib\pgcrypto.dll 67 | 68 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Transparent Data Encryption for PostgreSQL Free Edition 2 | ======================================================= 3 | 4 | This directory contains the source code of the Transparent Data Encryption for PostgreSQL. 5 | 6 | Transparent Data Encryption for PostgreSQL is Encryption tool for PostgreSQL. 7 | It adds encrypted data types to PostgreSQL. 8 | 9 | Please refer to the manual for detail information 10 | 11 | https://github.com/nec-postgres/tdeforpg/wiki/Manual(JA) 12 | 13 | If you interested in advanced TDE and data maintenance function. 14 | Please refer to the below URL 15 | 16 | http://jpn.nec.com/tdeforpg/ 17 | 18 | ======================================================= 19 | History 20 | 21 | 2018-07-11 V1.2.1.0 release 22 | 2017-03-10 V1.1.2.0 release 23 | 2015-12-10 V1.1.1.1 release 24 | 2015-12-07 V1.1.1.0 release 25 | 2015-06-05 V1.1.0.0 release 26 | -------------------------------------------------------------------------------- /RELEASE-NOTE.TXT: -------------------------------------------------------------------------------- 1 | Release v1.2.1.0 2 | 3 | Summary of changes in this version: 4 | 5 | - Added support for the following Windows platforms. 6 | - Windows Server 2012 7 | - Windows Server 2012 R2 8 | - Windows Server 2016 9 | - Added support for the following PostgreSQL Version 10 | - PostgreSQL 9.6 11 | - PostgreSQL 10 12 | - Added support for the AES-NI instruction set (high-speed encryption and decryption by AES supported processors) 13 | - Improve performance for encrypted/decrypted datatype. 14 | 15 | Migration to Version V1.2.1.0 16 | 17 | - A dump/restore using pg_dump and pg_restore is required. 18 | Please refer to the manual in wiki or UPGRADE-GUIDE.TXT 19 | 20 | Release v1.1.2.0 21 | 22 | This release contains following changes. 23 | - Added support for RHEL7. 24 | - Added support for PostgreSQL 9.5. 25 | - cipher_setup.sh: ERROR when validate/invalidate TDE feature to database 26 | which already done, now change to WARNING level with return code 0. 27 | - cipher_setup.sh: Security enhancement when activating TDE feature. 28 | 29 | Migration to Version V1.1.2.0 30 | A dump/restore using pg_dump and pg_restore is required. 31 | Please refer to the manual in wiki or UPGRADE-GUIDE.TXT 32 | 33 | Release v1.1.1.1 34 | 35 | This release contains a fix from 1.1.1.0. 36 | - Avoid possible name conflict of internal function. 37 | 38 | Migration to Version V1.1.1.1 39 | A dump/restore is not required for running 1.1.1.0 40 | Replace shared object file(.so) and run below script, and then restart PostgreSQL. 41 | - SOURCES/lib/init/cipher_key_function.sql 42 | 43 | Release v1.1.1.0 44 | 45 | This release contains following changes. 46 | - Added support for PostgreSQL 9.4 47 | - Avoid possible logging sensitive data issue when regist new encyprtion key. 48 | - Change pgtde_begin_session() and cipher_key_regist(); 49 | They cannot be executed before executing cipher_key_disable_log(). 50 | - Change cipher_key_disable_log(). 51 | Sensitive data will be masked instead of not logging. 52 | - Add pgtde_version() for checking version of tdeforpg. 53 | - Improve performance with encrypted datatype. 54 | 55 | Migration to Version V1.1.1.0 56 | A dump/restore using pg_dump and pg_restore is required. 57 | Please refer to the manual in wiki or UPGRADE-GUIDE.TXT 58 | 59 | Release v1.1.0.0 60 | 61 | This release contains following changes. 62 | - Change the category of ENCRYPT_TEXT type to 'S' and modified to allow equivalent cast of 63 | text types. From this change, '||' operator is enabled to use for ENCRYPT_TEXT. And 64 | ENCRYPT_TEXT can be casted to tsquery or tsvector. 65 | - Change implicitness of cast(TEXT as ENCRYPT_TEXT) from AS IMPLICIT to AS ASSIGNMENT. 66 | - Fix pgtde_begin_session/pgtde_end_session failed to execute when search_path is not public 67 | - Revise function volatility category of function. from this change, optimizer can generate 68 | a better execution plan. 69 | - Fix remain sensitive data in memory problem execute after pgtde_end_session function. 70 | 71 | Migration to Version V1.1.0.0 72 | A dump/restore using pg_dump and pg_restore is required. 73 | Please refer to the manual in wiki or UPGRADE-GUIDE.TXT 74 | 75 | -------------------------------------------------------------------------------- /SOURCES/bin/cipher_key_regist.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | START powershell -WindowStyle Hidden "& '%~dp0\cipher_key_regist.ps1' %*" 3 | exit 0 -------------------------------------------------------------------------------- /SOURCES/bin/cipher_key_regist.ps1: -------------------------------------------------------------------------------- 1 | # Powershell needs to run in STA mode to display WPF windows 2 | Param( 3 | [string]$configPath 4 | ) 5 | 6 | ########## Catch internal exception ########### 7 | trap { 8 | $exmessage = $Error[0] | Out-String 9 | [System.Windows.Forms.MessageBox]::Show("$exmessage", "Internal error occurred", "OK", "Error", "button1") 10 | return 11 | } 12 | 13 | if ([Threading.Thread]::CurrentThread.GetApartmentState() -eq "MTA"){ 14 | PowerShell -Sta -File $MyInvocation.MyCommand.Path 15 | return 16 | } 17 | 18 | Add-Type -AssemblyName presentationframework -ErrorAction Stop 19 | Add-Type -Assembly System.Windows.Forms -ErrorAction Stop 20 | 21 | ######################################################### 22 | ### Make sure only administrator can run this command ### 23 | 24 | function Test-IsAdmin { 25 | ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]:: GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") 26 | } 27 | 28 | ##################################################### 29 | # Set $env: # 30 | ##################################################### 31 | 32 | $env:PGHOST="localhost" 33 | $env:tdeforpgroot = $PSScriptRoot | %{$_ -replace "bin",""} 34 | $env:TDE_CURR_NUM_VERSION="1.2.1" 35 | $env:TDE_CURR_VERSION="Free Edition "+ $env:TDE_CURR_NUM_VERSION + ".0" 36 | 37 | ############## SetUP Status Inform ###################### 38 | 39 | ############### FORM ################ 40 | $height = 80 41 | $texbox_left = 210 42 | $label_size = 165 43 | $textbox_size = 190 44 | $button_left = 190 45 | $button_height = 20 46 | $Font = New-Object System.Drawing.Font("MS Gothic",10,[System.Drawing.FontStyle]::Bold) 47 | 48 | ### main form ### 49 | [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 50 | $Form = New-Object System.Windows.Forms.Form 51 | $Form.Text = "NEC TDE for PG Free Edition V" + $env:TDE_CURR_NUM_VERSION + " Cipher Key Regist" 52 | $Form.Size = New-Object System.Drawing.Size(520,430) 53 | $Form.StartPosition = "CenterScreen" 54 | $Form.KeyPreview = $True 55 | 56 | ### NEC label ### 57 | $NECLabel = New-Object System.Windows.Forms.Label 58 | $NECLabel.Location = New-Object System.Drawing.Size(20,25) 59 | $NECLabel.Size = New-Object System.Drawing.Size(150,30) 60 | $NECLabel.forecolor = "blue" 61 | $NECLabel.Text = "NEC TDE for PG`nFree Edition V" + $env:TDE_CURR_NUM_VERSION 62 | $NECLabel.Font = $Font 63 | $Form.Controls.Add($NECLabel) 64 | 65 | ### general label ### 66 | $GenaralLabel = New-Object System.Windows.Forms.Label 67 | $GenaralLabel.Location = New-Object System.Drawing.Size(20,$height) 68 | $GenaralLabel.Size = New-Object System.Drawing.Size(280,20) 69 | $GenaralLabel.Text = "Please enter the information to the following fields:" 70 | $Form.Controls.Add($GenaralLabel) 71 | 72 | $height = $height + 30 73 | ### current cipher key label ### 74 | $currentcipherkeylabel = New-Object System.Windows.Forms.Label 75 | $currentcipherkeylabel.Location = New-Object System.Drawing.Size(20,$height) 76 | $currentcipherkeylabel.Size = New-Object System.Drawing.Size($label_size,20) 77 | $currentcipherkeylabel.Text = "current cipher key:" 78 | $Form.Controls.Add($currentcipherkeylabel) 79 | 80 | ### current cipher key textbox ### 81 | $currentcipherkeyTextBox = New-Object System.Windows.Forms.MaskedTextBox 82 | $currentcipherkeyTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 83 | $currentcipherkeyTextBox.AutoSize = $false 84 | $currentcipherkeyTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 85 | $currentcipherkeyTextBox.PasswordChar = "*" 86 | $Form.Controls.Add($currentcipherkeyTextBox) 87 | 88 | ### current cipher key tips label ### 89 | $currentcipherkeytipslabel = New-Object System.Windows.Forms.Label 90 | $currentcipherkeytipslabel.Location = New-Object System.Drawing.Size( ($texbox_left + $textbox_size),$height) 91 | $currentcipherkeytipslabel.Size = New-Object System.Drawing.Size(40,20) 92 | $currentcipherkeytipslabel.Text = "(*)" 93 | $Form.Controls.Add($currentcipherkeytipslabel) 94 | 95 | $height = $height + 30 96 | ### new cipher key label ### 97 | $newcipherkeylabel = New-Object System.Windows.Forms.Label 98 | $newcipherkeylabel.Location = New-Object System.Drawing.Size(20,$height) 99 | $newcipherkeylabel.Size = New-Object System.Drawing.Size($label_size,20) 100 | $newcipherkeylabel.Text = "new cipher key:" 101 | $Form.Controls.Add($newcipherkeylabel) 102 | 103 | ### new cipher key textbox ### 104 | $newcipherkeyTextBox = New-Object System.Windows.Forms.MaskedTextBox 105 | $newcipherkeyTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 106 | $newcipherkeyTextBox.AutoSize = $false 107 | $newcipherkeyTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 108 | $newcipherkeyTextBox.PasswordChar = "*" 109 | $Form.Controls.Add($newcipherkeyTextBox) 110 | 111 | $height = $height + 30 112 | ### cipher key algorithm label ### 113 | $cipherkeyalgorithmlabel = New-Object System.Windows.Forms.Label 114 | $cipherkeyalgorithmlabel.Location = New-Object System.Drawing.Size(20,$height) 115 | $cipherkeyalgorithmlabel.Size = New-Object System.Drawing.Size($label_size,20) 116 | $cipherkeyalgorithmlabel.Text = "new cipher key algorithm:" 117 | $Form.Controls.Add($cipherkeyalgorithmlabel) 118 | 119 | ### retype new current cipher key textbox ### 120 | $cipherkeyalgorithmComboBox = New-Object System.Windows.Forms.ComboBox 121 | $cipherkeyalgorithmComboBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 122 | $cipherkeyalgorithmComboBox.AutoSize = $false 123 | $cipherkeyalgorithmComboBox.Size = New-Object System.Drawing.Size($textbox_size,23) 124 | $cipherkeyalgorithmComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList 125 | $cipherkeyalgorithmComboBox.Items.Add("aes") 126 | $cipherkeyalgorithmComboBox.Items.Add("bf") 127 | $cipherkeyalgorithmComboBox.SelectedIndex = 0 128 | $Form.Controls.Add($cipherkeyalgorithmComboBox) 129 | 130 | $height = $height + 30 131 | ### port label ### 132 | $portlabel = New-Object System.Windows.Forms.Label 133 | $portlabel.Location = New-Object System.Drawing.Size(20,$height) 134 | $portlabel.Size = New-Object System.Drawing.Size($label_size,20) 135 | $portlabel.Text = "Database Port Number:" 136 | $Form.Controls.Add($portlabel) 137 | 138 | ### port textbox ### 139 | $portTextBox = New-Object System.Windows.Forms.TextBox 140 | $portTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 141 | $portTextBox.AutoSize = $false 142 | $portTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 143 | $Form.Controls.Add($portTextBox) 144 | 145 | $height = $height + 30 146 | ### DB name label ### 147 | $dbnamelabel = New-Object System.Windows.Forms.Label 148 | $dbnamelabel.Location = New-Object System.Drawing.Size(20,$height) 149 | $dbnamelabel.Size = New-Object System.Drawing.Size($label_size,20) 150 | $dbnamelabel.Text = "Database Name:" 151 | $Form.Controls.Add($dbnamelabel) 152 | 153 | ### DB name textbox ### 154 | $dbnameTextBox = New-Object System.Windows.Forms.TextBox 155 | $dbnameTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 156 | $dbnameTextBox.AutoSize = $false 157 | $dbnameTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 158 | $Form.Controls.Add($dbnameTextBox) 159 | 160 | $height = $height + 30 161 | ### user name label ### 162 | $usernamelabel = New-Object System.Windows.Forms.Label 163 | $usernamelabel.Location = New-Object System.Drawing.Size(20,$height) 164 | $usernamelabel.Size = New-Object System.Drawing.Size($label_size,20) 165 | $usernamelabel.Text = "Database User Name:" 166 | $Form.Controls.Add($usernamelabel) 167 | 168 | ### user name textbox ### 169 | $usernameTextBox = New-Object System.Windows.Forms.TextBox 170 | $usernameTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 171 | $usernameTextBox.AutoSize = $false 172 | $usernameTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 173 | $Form.Controls.Add($usernameTextBox) 174 | 175 | $height = $height + 30 176 | ### postgres access password label ### 177 | $pgaccesslabel = New-Object System.Windows.Forms.Label 178 | $pgaccesslabel.Location = New-Object System.Drawing.Size(20,$height) 179 | $pgaccesslabel.Size = New-Object System.Drawing.Size($label_size,20) 180 | $pgaccesslabel.Text = "Database User Password:" 181 | $Form.Controls.Add($pgaccesslabel) 182 | 183 | ### password textbox ### 184 | $passwordTextBox = New-Object System.Windows.Forms.MaskedTextBox 185 | $passwordTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 186 | $passwordTextBox.AutoSize = $false 187 | $passwordTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 188 | $passwordTextBox.PasswordChar = "*" 189 | $Form.Controls.Add($passwordTextBox) 190 | 191 | $height = $height + 30 192 | ### postgresql install folder label ### 193 | $pginstalllabel = New-Object System.Windows.Forms.Label 194 | $pginstalllabel.Location = New-Object System.Drawing.Size(20,$height) 195 | $pginstalllabel.Size = New-Object System.Drawing.Size($label_size,20) 196 | $pginstalllabel.Text = "PostgreSQL Install Folder:" 197 | $Form.Controls.Add($pginstalllabel) 198 | 199 | ### postgresql install folder textbox ### 200 | $pginstallTextBox = New-Object System.Windows.Forms.TextBox 201 | $pginstallTextBox.Location = New-Object System.Drawing.Size($texbox_left,$height) 202 | $pginstallTextBox.AutoSize = $false 203 | $pginstallTextBox.Size = New-Object System.Drawing.Size($textbox_size,23) 204 | $Form.Controls.Add($pginstallTextBox) 205 | 206 | ### folderbrowser dialog ### 207 | $fd = New-Object System.Windows.Forms.FolderBrowserDialog 208 | $fd.Description = "Select PostgreSQL Install Folder" 209 | $fd.ShowNewFolderButton = $false 210 | 211 | ### folderbrowser dialog button ### 212 | $fdButton = New-Object System.Windows.Forms.Button 213 | $fdButton.Location = New-Object System.Drawing.Size( ($texbox_left + $textbox_size) ,$height) 214 | $fdButton.Size = New-Object System.Drawing.Size(23,23) 215 | $fdButton.Text = "..." 216 | $Form.Controls.Add($fdButton) 217 | 218 | $height = $height + 40 219 | ### tips label1 ### 220 | $tipslabel1 = New-Object System.Windows.Forms.Label 221 | $tipslabel1.Location = New-Object System.Drawing.Size(20,$height) 222 | $tipslabel1.Size = New-Object System.Drawing.Size( ($label_size + $textbox_size) ,20) 223 | $tipslabel1.Text = "(*) : Don't need to enter for the first time." 224 | $Form.Controls.Add($tipslabel1) 225 | 226 | $button_left = $button_left + 100 227 | ### regist button ### 228 | $registButton = New-Object System.Windows.Forms.Button 229 | $registButton.Location = New-Object System.Drawing.Size($button_left,$button_height) 230 | $registButton.Size = New-Object System.Drawing.Size(90,35) 231 | $registButton.Text = "Key Regist" 232 | $Form.Controls.Add($registButton) 233 | 234 | $button_left = $button_left + 100 235 | ### exit button ### 236 | $ExitButton = New-Object System.Windows.Forms.Button 237 | $ExitButton.Location = New-Object System.Drawing.Size($button_left ,$button_height) 238 | $ExitButton.Size = New-Object System.Drawing.Size(90,35) 239 | $ExitButton.Text = "Exit" 240 | $Form.Controls.Add($ExitButton) 241 | 242 | $button_height = $button_height + 50 243 | ### Clear infor button ### 244 | $clearButton = New-Object System.Windows.Forms.Button 245 | $clearButton.Location = New-Object System.Drawing.Size($button_left ,$button_height) 246 | $clearButton.Size = New-Object System.Drawing.Size(70,30) 247 | $clearButton.Text = "Clear" 248 | 249 | ###################################################### 250 | # clear input information # 251 | ###################################################### 252 | function clear_form { 253 | trap { 254 | $exmessage = $Error[0] | Out-String 255 | [System.Windows.Forms.MessageBox]::Show("$exmessage", "Internal error occurred", "OK", "Error", "button1") 256 | $Form.Close() 257 | return 258 | } 259 | 260 | $portTextBox.Text = "" 261 | $dbnameTextBox.Text = "" 262 | $usernameTextBox.Text = "" 263 | $passwordTextBox.Text = "" 264 | $pginstallTextBox.Text = "" 265 | $currentcipherkeyTextBox.Text = "" 266 | $newcipherkeyTextBox.Text = "" 267 | $cipherkeyalgorithmComboBox.SelectedIndex = 0 268 | } 269 | $clearButton.Add_Click({ clear_form }) 270 | $Form.Controls.Add($clearButton) 271 | 272 | $Form.Topmost = $True 273 | 274 | ################ END MAIN FORM ################ 275 | 276 | 277 | ########## MAIN ########### 278 | ## check Administrators ### 279 | if (!(Test-IsAdmin)){ 280 | [System.Windows.Forms.MessageBox]::Show("You must be Administrators to execute this action.","Not Administrator","OK","Error","button1") 281 | $Form.Close() 282 | return 283 | } 284 | 285 | ##################################################### 286 | # Connection Test Function # 287 | ##################################################### 288 | function connection_test{ 289 | $con = & $env:PSQLCMD -w -t -A -c "select 1" 2>&1 290 | if($con -eq 1) { 291 | ### check is super user ### 292 | $super=& $env:PSQLCMD -X -t -A -c "select usesuper from pg_user where usename='$env:PGUSER'" 293 | if ($super -ne "t"){ 294 | [System.Windows.Forms.MessageBox]::Show("Must be superuser to execute this action.","Could not Connect","OK","Error","button1") 295 | return 1 296 | } 297 | } 298 | else { 299 | [System.Windows.Forms.MessageBox]::Show("Could not connect to the database.","Could not Connect","OK","Error","button1") 300 | return 1 301 | } 302 | } 303 | 304 | ##################################################### 305 | # CHECK template1 function # 306 | ##################################################### 307 | function check_template1{ 308 | if($MyDB -ieq "template1") { 309 | [System.Windows.Forms.MessageBox]::Show("Could not use template1 database.","Could not use template1","OK","Error","button1") 310 | return 1 311 | } 312 | } 313 | 314 | ##################################################### 315 | # CHECK FORM function # 316 | ##################################################### 317 | 318 | ### Check newcipherkey #### 319 | function check_form_newcipherkey{ 320 | if([string]::IsNullOrWhiteSpace($newcipherkeyTextBox.Text)) { 321 | [System.Windows.Forms.MessageBox]::Show("The length of new cipher key must not be zero.","Object length zero","OK","Error","button1") 322 | return 1 323 | } 324 | } 325 | 326 | ### Check cipherkeyalgorithm #### 327 | function check_form_cipherkeyalgorithm{ 328 | if([string]::IsNullOrWhiteSpace($cipherkeyalgorithmComboBox.Text)) { 329 | [System.Windows.Forms.MessageBox]::Show("The length of new cipher key algorithm must not be zero.","Object length zero","OK","Error","button1") 330 | return 1 331 | } 332 | } 333 | 334 | ### Check Port #### 335 | function check_form_port{ 336 | if([string]::IsNullOrWhiteSpace($portTextBox.Text)) { 337 | [System.Windows.Forms.MessageBox]::Show("The length of Port must not be zero.","Object length zero","OK","Error","button1") 338 | return 1 339 | } elseif(!($portTextBox.Text -match "^\d+$")) { 340 | [System.Windows.Forms.MessageBox]::Show("Port must be integer.","Port must be integer","OK","Error","button1") 341 | return 1 342 | } 343 | } 344 | 345 | ### Check DB Name #### 346 | function check_form_dbname{ 347 | if([string]::IsNullOrWhiteSpace($dbnameTextBox.Text)) { 348 | [System.Windows.Forms.MessageBox]::Show("The length of Database must not be zero.","Object length zero","OK","Error","button1") 349 | return 1 350 | } 351 | } 352 | 353 | ### Check SuperUser #### 354 | function check_form_user{ 355 | if([string]::IsNullOrWhiteSpace($usernameTextBox.Text)) { 356 | [System.Windows.Forms.MessageBox]::Show("The length of Superuser must not be zero.","Object length zero","OK","Error","button1") 357 | return 1 358 | } 359 | } 360 | 361 | ### Check DB Password #### 362 | function check_form_dbpass{ 363 | if([string]::IsNullOrWhiteSpace($passwordTextBox.Text)) { 364 | [System.Windows.Forms.MessageBox]::Show("The length of Database Password must not be zero.","Object length zero","OK","Error","button1") 365 | return 1 366 | } 367 | } 368 | 369 | ### Check PostgreSQL Install Folder #### 370 | function check_form_pginsdir{ 371 | if([string]::IsNullOrWhiteSpace($pginstallTextBox.Text)) { 372 | [System.Windows.Forms.MessageBox]::Show("The length of PostgreSQL Install Folder must not be zero.","Object length zero","OK","Error","button1") 373 | return 1 374 | } 375 | } 376 | 377 | ##################################################### 378 | # Confirmation function # 379 | ##################################################### 380 | 381 | #### Validate ##### 382 | function confirmation_register{ 383 | $msgBoxInput = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to register the cipher key?","Register confirm","YesNo","Question","button2") 384 | switch ($msgBoxInput) { 385 | 'Yes' { 386 | return 0 387 | break 388 | } 389 | 'No' { 390 | [System.Windows.Forms.MessageBox]::Show("Registering operation canceled.","Operation Canceled","OK","Information","button1") 391 | return 1 392 | break 393 | } 394 | } 395 | } 396 | 397 | ##### Exit ##### 398 | function confirmation_exit{ 399 | $msgBoxInput = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to exit?", "Exit confirm", "YesNo", "Question","button2") 400 | switch ($msgBoxInput) { 401 | 'Yes' { 402 | return 1 403 | break 404 | } 405 | 'No' { 406 | return 0 407 | break 408 | } 409 | } 410 | } 411 | 412 | ################## Push END ##################### 413 | 414 | function Push_Exit { 415 | trap { 416 | $exmessage = $Error[0] | Out-String 417 | [System.Windows.Forms.MessageBox]::Show("$exmessage", "Internal error occurred", "OK", "Error", "button1") 418 | $Form.Close() 419 | return 420 | } 421 | 422 | $ret = confirmation_exit 423 | if($ret -eq 1){ 424 | $Form.Close() 425 | } 426 | } 427 | 428 | $ExitButton.add_Click({ Push_Exit }) 429 | 430 | 431 | #################### Push Regist #################### 432 | 433 | function Push_Regist { 434 | trap { 435 | $exmessage = $Error[0] | Out-String 436 | [System.Windows.Forms.MessageBox]::Show("$exmessage", "Internal error occurred", "OK", "Error", "button1") 437 | $Form.Close() 438 | return 439 | } 440 | 441 | ### register operation confirm ### 442 | $ret = confirmation_register 443 | if($ret -eq 1){ 444 | return 445 | } 446 | #################################### 447 | 448 | ### CHECK input connection parameter for psql ### 449 | $ret = check_form_newcipherkey 450 | if($ret -eq 1){ 451 | return 452 | } 453 | 454 | $ret = check_form_cipherkeyalgorithm 455 | if($ret -eq 1){ 456 | return 457 | } 458 | 459 | $ret = check_form_port 460 | if($ret -eq 1){ 461 | return 462 | } 463 | 464 | $ret = check_form_dbname 465 | if($ret -eq 1){ 466 | return 467 | } 468 | 469 | $ret = check_form_user 470 | if($ret -eq 1){ 471 | return 472 | } 473 | 474 | $ret = check_form_dbpass 475 | if($ret -eq 1){ 476 | return 477 | } 478 | 479 | $ret = check_form_pginsdir 480 | if($ret -eq 1){ 481 | return 482 | } 483 | 484 | ### Setting form information #### 485 | $CurrentKey = $currentcipherkeyTextBox.Text 486 | $NewKey = $newcipherkeyTextBox.Text 487 | $KeyAlgorithm = $cipherkeyalgorithmComboBox.Text 488 | $MyPort = $portTextBox.Text 489 | $MyDB = $dbnameTextBox.Text 490 | $MyUid = $usernameTextBox.Text 491 | $MyPass = $passwordTextBox.Text 492 | $PGPATH = $pginstallTextBox.Text 493 | $env:PGPORT = "$MyPort" 494 | $env:PGDATABASE = "$MyDB" 495 | $env:SuperU = "$MyUid" 496 | $env:SuperP = "$MyPass" 497 | $env:PGUSER = $env:SuperU 498 | $env:PGPASSWORD = $env:SuperP 499 | $LIBPQ= Join-Path $PGPATH "bin\libpq.dll" 500 | $env:PSQLCMD = Join-Path $PGPATH "bin\psql.exe" 501 | #################################### 502 | 503 | if (!(Test-Path $env:PSQLCMD)) { 504 | [System.Windows.Forms.MessageBox]::Show("psql file does not exist. File name: $env:PSQLCMD `nHINT: Check the PostgreSQL Install Folder, and Try again","psql file not exist","OK","Error","button1") 505 | return 506 | } 507 | 508 | if (!(Test-Path $LIBPQ)) { 509 | [System.Windows.Forms.MessageBox]::Show("dll file does not exist. File name: $LIBPQ `nHINT: Check the PostgreSQL Install Folder, and Try again","dll file not exist","OK","Error","button1") 510 | return 511 | } 512 | 513 | #check DB if = template1 514 | $ret = check_template1 515 | if($ret -eq 1){ 516 | return 517 | } 518 | 519 | ################################################# 520 | 521 | ##### connection test ##### 522 | $ret = connection_test 523 | if($ret -eq 1){ 524 | return 525 | } 526 | ########################### 527 | 528 | # Change display of form 529 | $GenaralLabel.Text = "Registering..." 530 | 531 | $global:LASTEXITCODE = 0 532 | $filename = Get-Date -Format "yyyyMMdd-HHmmss" 533 | $env:ERRFILE = $env:tdeforpgroot + "bin\error_" + $filename 534 | "select cipher_key_disable_log(); 535 | select cipher_key_regist('$CurrentKey', '$NewKey','$KeyAlgorithm'); 536 | select cipher_key_enable_log();" | & $env:PSQLCMD --set ON_ERROR_STOP=ON -1 2>$env:ERRFILE 1>$env:null 537 | 538 | if($global:LASTEXITCODE -ne 0) { 539 | $GenaralLabel.Text = "Please enter the information to the following fields:" 540 | [System.Windows.Forms.MessageBox]::Show("Could not register cipher key.`nHINT : Please see $env:ERRFILE for detail.","Register Failed","OK","Error","button1") 541 | return 542 | } 543 | # remove error log file if register OK. 544 | Remove-Item $env:ERRFILE 545 | 546 | [System.Windows.Forms.MessageBox]::Show("cipher key registered!","Register success!","OK","Information","button1") 547 | $GenaralLabel.Text = "Please enter the information to the following fields:" 548 | } 549 | 550 | $registButton.add_Click({ Push_Regist }) 551 | 552 | #################### Push FolderDialog #################### 553 | 554 | function Push_FolderDialog { 555 | trap { 556 | $exmessage = $Error[0] | Out-String 557 | [System.Windows.Forms.MessageBox]::Show("$exmessage", "Internal error occurred", "OK", "Error", "button1") 558 | $Form.Close() 559 | return 560 | } 561 | 562 | if($fd.ShowDialog($Form) -eq [System.Windows.Forms.DialogResult]::OK) { 563 | $pginstallTextBox.Text = $fd.SelectedPath 564 | } 565 | } 566 | 567 | $fdButton.add_Click({ Push_FolderDialog }) 568 | 569 | $Form.Add_Shown({$Form.Activate()}) 570 | $Form.ShowDialog() | out-null 571 | -------------------------------------------------------------------------------- /SOURCES/bin/cipher_key_regist.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | ################################################### 4 | # Setting Necessary Path. # 5 | ################################################### 6 | export PROGRAMNAME=`basename $0` 7 | #get program root path 8 | export CURRENTPATH=`echo $0|sed "s/${PROGRAMNAME}$//g"` 9 | 10 | #change directory to program root 11 | if [ -n "$CURRENTPATH" ]; then 12 | cd $CURRENTPATH 13 | fi 14 | 15 | #set external program(psql) execution path 16 | export PGPATH=$1 17 | export LD_PRELOAD=${PGPATH}/lib/libpq.so.5 18 | 19 | #set the psql path 20 | export PSQLPATH=${PGPATH}/bin/ 21 | 22 | export PATH=${PSQLPATH}:${PATH} 23 | export KEYTBL="cipher_key_table" 24 | 25 | 26 | ################################################### 27 | # Setting PSQL Environment # 28 | ################################################### 29 | export PGOPTIONS="-c client_min_messages=ERROR" 30 | 31 | ################################################### 32 | # Input PSQL Parameter Function # 33 | ################################################### 34 | input_psql_param(){ 35 | echo "=== Database connection information ==="; 36 | #set the delimiter to newline 37 | OLDIFS="${IFS}" 38 | IFS=$'\n' 39 | echo -n 'Please enter database server port to connect : ' 40 | read PORT; 41 | 42 | echo -n 'Please enter database user name to connect : ' 43 | read USER; 44 | 45 | echo -n 'Please enter password for authentication : ' 46 | stty -echo 47 | read PASS; 48 | stty echo 49 | echo 50 | 51 | echo -n 'Please enter database name to connect : ' 52 | read DB; 53 | if [ "${DB}" = "template1" ];then echo "ERROR: Can not use template1 database";exit 1;fi 54 | if [ "${DB}" = "" ];then echo "ERROR: The length of database name must not be zero";exit 1;fi 55 | IFS="${OLDIFS}" 56 | 57 | export PGHOST=localhost 58 | export PGDATABASE="${DB}" 59 | export PGPORT="${PORT}" 60 | export PGPASSWORD="${PASS}" 61 | export PGUSER="${USER}" 62 | 63 | return 0; 64 | } 65 | 66 | ##################################################### 67 | # Connection Test Function # 68 | ##################################################### 69 | connection_test(){ 70 | psql -w -c "select 1" 1>/dev/null ; 71 | return $? 72 | } 73 | 74 | ##################################################### 75 | # Register New Cipher Key Function # 76 | ##################################################### 77 | cipher_key_regist(){ 78 | #set the delimiter to newline 79 | OLDIFS="${IFS}" 80 | IFS=$'\n' 81 | 82 | echo "=== Regist new cipher key ==="; 83 | NUMBER_OF_KEY=`psql -t -c "SELECT COUNT(*) FROM ${KEYTBL};"` 84 | if [ $NUMBER_OF_KEY -ge 1 ]; then 85 | echo -n 'Please enter the current cipher key : ' 86 | stty -echo 87 | read CURRENT_CIPHER_KEY 88 | stty echo 89 | echo 90 | else 91 | CURRENT_CIPHER_KEY='init' 92 | fi 93 | 94 | echo -n 'Please enter the new cipher key : ' 95 | stty -echo 96 | read NEW_CIPHER_KEY; 97 | stty echo 98 | echo 99 | 100 | echo -n 'Please retype the new cipher key : ' 101 | stty -echo 102 | read RETYPE_NEW_CIPHER_KEY; 103 | stty echo 104 | echo 105 | if [ "$RETYPE_NEW_CIPHER_KEY" != "$NEW_CIPHER_KEY" ]; then 106 | echo 'Cipher key do not match' 107 | exit; 108 | fi 109 | 110 | echo -n 'Please enter the algorithm for new cipher key : ' 111 | read ALGORITHM; 112 | echo 113 | while true; do 114 | echo -n 'Are you sure to register new cipher key(y/n) : ' 115 | read SELECT; 116 | case $SELECT in 117 | [Yy] ) break;; 118 | [Nn] ) exit;; 119 | * ) echo "Please enter y or n";; 120 | esac 121 | done 122 | 123 | (psql -w </dev/null 129 | 130 | return $? 131 | } 132 | 133 | ##################################################### 134 | # Connection Test Function # 135 | ##################################################### 136 | connection_test(){ 137 | psql -w -c "select 1" 1>/dev/null ; 138 | return $? 139 | } 140 | 141 | ################################################### 142 | # Main Process # 143 | ################################################### 144 | 1>/dev/null 145 | if [ $# -ne 1 ]; then 146 | echo "usage: sh bin/cipher_key_regist.sh POSTGRESQL_DIR" 147 | echo "Please specify PostgreSQL installed directory" 148 | exit 1 149 | fi 150 | 151 | #input connection parameter for psql 152 | input_psql_param 153 | 154 | #connection test 155 | connection_test 156 | if [ $? -ne 0 ];then 157 | echo "ERROR: Could not connect to the database"; 158 | exit 1; 159 | fi 160 | 161 | #check existing of cipher_key_table 162 | CIPHER_EXIST=`psql -t -c "SELECT COUNT(*) FROM PG_TABLES WHERE TABLENAME='${KEYTBL}';"` 163 | if [ $CIPHER_EXIST -eq 0 ]; then 164 | echo "ERROR: Transparent data encryption feature has not been activated yet" 165 | exit 1; 166 | fi 167 | 168 | cipher_key_regist 169 | -------------------------------------------------------------------------------- /SOURCES/bin/cipher_setup.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | START powershell -WindowStyle Hidden "& '%~dp0\cipher_setup.ps1' %*" 3 | exit 0 -------------------------------------------------------------------------------- /SOURCES/bin/cipher_setup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | ################################################### 4 | # Setting Necessary Path. # 5 | ################################################### 6 | export PROGRAMNAME=`basename $0` 7 | #get program root path 8 | export CURRENTPATH=`echo $0|sed "s/${PROGRAMNAME}$//g"` 9 | 10 | #change directory to program root 11 | if [ -n "$CURRENTPATH" ]; then 12 | cd $CURRENTPATH 13 | fi 14 | 15 | #set external program(psql) execution path 16 | export PGPATH=$1 17 | export LD_PRELOAD=${PGPATH}/lib/libpq.so.5 18 | 19 | #set the psql path 20 | export PSQLPATH=${PGPATH}/bin/ 21 | #set initscript path 22 | export SCRPATH=../lib/init 23 | #activate db file directory path 24 | export INSTPATH=../sys 25 | 26 | #PostgreSQL version number 27 | PGVERSION= 28 | 29 | export PATH=${PSQLPATH}:${PATH} 30 | 31 | 32 | ################################################### 33 | # Setting PSQL Environment # 34 | ################################################### 35 | export PGOPTIONS="-c client_min_messages=ERROR" 36 | 37 | 38 | ################################################### 39 | # Setting Common Variable # 40 | ################################################### 41 | export KEYTBL="cipher_key_table" 42 | export NOKEYTBL="cipher_key_table_uninst" 43 | 44 | export ERRFILE="error_`date +%Y%m%d-%H%M%S`.log" 45 | 46 | ################################################### 47 | # Input PSQL Parameter Function # 48 | ################################################### 49 | input_psql_param(){ 50 | 51 | #set the delimiter to newline 52 | OLDIFS="${IFS}" 53 | IFS=$'\n' 54 | echo -n 'Please enter database server port to connect : ' 55 | read PORT; 56 | 57 | echo -n 'Please enter database user name to connect : ' 58 | read USER; 59 | 60 | echo -n 'Please enter password for authentication : ' 61 | stty -echo 62 | read PASS; 63 | stty echo 64 | echo 65 | 66 | echo -n 'Please enter database name to connect : ' 67 | read DB; 68 | if [ "${DB}" = "template1" ];then echo "ERROR: Can not use template1 database";exit 1;fi 69 | if [ "${DB}" = "" ];then echo "ERROR: The length of database name must not be zero";exit 1;fi 70 | IFS="${OLDIFS}" 71 | 72 | export PGHOST=localhost 73 | export PGDATABASE="${DB}" 74 | export PGPORT="${PORT}" 75 | export PGPASSWORD="${PASS}" 76 | export PGUSER="${USER}" 77 | 78 | return 0; 79 | } 80 | 81 | ##################################################### 82 | # Connection Test Function # 83 | ##################################################### 84 | connection_test(){ 85 | psql -w -c "select 1" 1>/dev/null ; 86 | return $? 87 | } 88 | 89 | ##################################################### 90 | # File Exist Test Function # 91 | ##################################################### 92 | file_exist_check(){ 93 | if [ ! -f "$1" ]; 94 | then 95 | echo "ERROR: There is not exist a definition-script : $1" 96 | rm -f "${INSTALLFILE}" 97 | exit 1; 98 | fi 99 | } 100 | 101 | ##################################################### 102 | # Decide Function # 103 | ##################################################### 104 | decide(){ 105 | prompt="Please input [Yes/No] > " 106 | status=0 107 | 108 | while : ; do 109 | line="" 110 | read -p "${prompt}" line 111 | case "$line" in 112 | Y|y|[Yy]es|YES) 113 | status=0 114 | break 115 | ;; 116 | N|n|[Nn]o|NO) 117 | status=1 118 | break 119 | ;; 120 | esac 121 | 122 | echo "ERROR: Invalid input." 123 | done 124 | 125 | return $status 126 | } 127 | 128 | ################################################### 129 | # Output Parameter Function # 130 | ################################################### 131 | printErr(){ 132 | echo "error occured at `date +%Y-%m-%d-%H:%M:%S`" 133 | echo "parameters:" 134 | echo " user:${PGUSER}" 135 | echo " db:${PGDATABASE}" 136 | echo " port:${PGPORT}" 137 | echo " menu:$select" 138 | echo 139 | } 140 | 141 | ################################################### 142 | # Validate Function # 143 | ################################################### 144 | validate(){ 145 | 146 | ######## 147 | # initial activate … true 148 | # reactivate … false 149 | ######## 150 | VALIDATE_NEW=false 151 | 152 | #input connection parameter for psql 153 | input_psql_param 154 | 155 | #connection test 156 | connection_test 157 | if [ $? -ne 0 ]; 158 | then 159 | echo "ERROR: Could not connect to the database"; 160 | exit 1; 161 | fi 162 | 163 | # get PGVERSION 164 | PGVERSION=`psql -t -c "show server_version_num;"` 165 | 166 | #check existing of cipher_key_table 167 | CIPHER_EXIST=`psql -t -c "SELECT COUNT(*) FROM PG_TABLES WHERE TABLENAME='${KEYTBL}';"` 168 | if [ $CIPHER_EXIST -eq 1 ]; 169 | then 170 | echo "WARN: Transparent data encryption function has already been activated" 171 | exit 0; 172 | fi 173 | 174 | 175 | #store all activation query to file for execution 176 | INSTALLFILE="${INSTPATH}"/"${DB}".cipher.inst 177 | if [ -f "${INSTALLFILE}" ]; 178 | then 179 | echo "ERROR: Lock file already exists. File name: ${INSTALLFILE}" 180 | echo "HINT: Remove the Lock file, and Try again" 181 | exit 1; 182 | fi 183 | 184 | #check existing of cipher_key_table_uninst 185 | CIPHER_NOEXIST=`psql -t -c "SELECT COUNT(*) FROM PG_TABLES WHERE TABLENAME='${NOKEYTBL}';"` 186 | if [ $CIPHER_NOEXIST -ne 0 ]; 187 | then 188 | #exits -- reactivate 189 | VALIDATE_NEW=false 190 | echo "WARN: Are you sure you want to reactivate the transparent data encryption feature? " 191 | decide 192 | if [ $? -eq 1 ]; 193 | then 194 | echo "INFO: terminated" 195 | exit 0; 196 | fi 197 | 198 | 199 | #init activation file 200 | echo "" > "${INSTALLFILE}" 201 | #only root can read this file 202 | chmod 600 "${INSTALLFILE}" 203 | #remove installation file, if installation is terminated abnormally 204 | trap 'rm -f "${INSTALLFILE}"; exit 1;' 1 2 3 15 205 | #rename cipher_key_table_uninst to cipher_key_table 206 | QUERY="ALTER TABLE \"${NOKEYTBL}\" RENAME TO \"${KEYTBL}\";"; 207 | echo "${QUERY}" >> "${INSTALLFILE}" 208 | else 209 | #not exists -- initial activate 210 | VALIDATE_NEW=true 211 | #execute CREATE LANGUAGE 212 | psql -c "CREATE OR REPLACE LANGUAGE plpgsql;" 2> /dev/null 213 | 214 | file_exist_check "${SCRPATH}/cipher_definition.sql" 215 | file_exist_check "${SCRPATH}/cipher_key_function.sql" 216 | 217 | #init activation file 218 | echo "" > "${INSTALLFILE}" 219 | #only root can read this file 220 | chmod 600 "${INSTALLFILE}" 221 | #remove installation file, if installation is terminated abnormally 222 | trap 'rm -f "${INSTALLFILE}"; exit 1;' 1 2 3 15 223 | cat "${SCRPATH}/cipher_definition.sql" >> "${INSTALLFILE}" 224 | cat "${SCRPATH}/cipher_key_function.sql" >> "${INSTALLFILE}" 225 | echo "GRANT SELECT ON cipher_key_table TO PUBLIC;" >> "${INSTALLFILE}" 226 | fi 227 | 228 | file_exist_check "${SCRPATH}/common_session_create.sql" 229 | #define session function A 230 | cat "${SCRPATH}/common_session_create.sql" >> "${INSTALLFILE}" 231 | 232 | # add parallel safe setting for PostgreSQL 9.6 and greater 233 | if [ ${PGVERSION} -ge 90600 ]; then 234 | file_exist_check "${SCRPATH}/pgtde_parallel_safe_setting.sql" 235 | cat "${SCRPATH}/pgtde_parallel_safe_setting.sql" >> "${INSTALLFILE}" 236 | fi 237 | 238 | #run all query in installation file using transaction 239 | psql --set ON_ERROR_STOP=ON -1 -f "${INSTALLFILE}" 1>/dev/null 2>"${ERRFILE}" 240 | if [ `wc -c < ${ERRFILE}` -gt 0 ]; 241 | then 242 | printErr >> "${ERRFILE}" 243 | echo "ERROR: Could not activate transparent data encryption feature" 244 | echo "HINT : Please see ${ERRFILE} for detail" 245 | rm -f "${INSTALLFILE}" 246 | exit 1; 247 | fi 248 | 249 | #empty the INSTALLFILE 250 | echo " " > "${INSTALLFILE}" 251 | 252 | #remove empty error log 253 | rm -rf "${ERRFILE}" 254 | 255 | echo "INFO: Transparent data encryption feature has been activated" 256 | 257 | return 0; 258 | } 259 | 260 | ################################################### 261 | # Invalidate Function # 262 | ################################################### 263 | invalidate(){ 264 | 265 | 266 | #input connection parameters for psql 267 | input_psql_param 268 | 269 | #connection test 270 | connection_test 271 | if [ $? -ne 0 ];then echo "ERROR: Could not connect to the database";exit 1;fi 272 | 273 | #check existence of cipher_key_table 274 | CIPHER_EXIST=`psql -t -c "SELECT COUNT(*) FROM PG_TABLES WHERE TABLENAME='${KEYTBL}';"` 275 | if [ $CIPHER_EXIST -eq 0 ]; 276 | then #cipher_key_table is not exists 277 | echo "WARN: Transparent data encryption feature has not been activated yet" 278 | exit 0 279 | fi 280 | 281 | #store all query for inactivate to file 282 | INSTALLFILE="${INSTPATH}"/"${DB}".cipher.inst 283 | if [ ! -f "${INSTALLFILE}" ]; 284 | then 285 | echo "ERROR: Lock file does not exist. File name : ${INSTALLFILE}" 286 | exit 1; 287 | fi 288 | #init inactivate file 289 | echo "" > "${INSTALLFILE}" 290 | #only root can read this file 291 | chmod 600 "${INSTALLFILE}" 292 | #drop session function C 293 | echo "DROP FUNCTION PGTDE_BEGIN_SESSION(TEXT);" >> "${INSTALLFILE}" 294 | #drop end session function 295 | echo "DROP FUNCTION PGTDE_END_SESSION();" >> "${INSTALLFILE}" 296 | 297 | 298 | 299 | #rename cipher_key_table 300 | QUERY="ALTER TABLE \"${KEYTBL}\" RENAME TO \"${NOKEYTBL}\";"; 301 | echo "${QUERY}" >> "${INSTALLFILE}" 302 | 303 | 304 | #run all query in inactivation file using transaction 305 | psql --set ON_ERROR_STOP=ON -1 -f "${INSTALLFILE}" 1>/dev/null 2>"${ERRFILE}" 306 | if [ `wc -c < ${ERRFILE}` -gt 0 ]; 307 | then 308 | printErr >> "${ERRFILE}" 309 | echo "ERROR: Could not inactivate the transparent data encryption feature" 310 | echo "HINT : Please see ${ERRFILE} for detail" 311 | exit 1; 312 | fi 313 | #remove empty error log 314 | rm -rf "${ERRFILE}" 315 | 316 | #remove dbname.cipher.inst 317 | rm -f "${INSTALLFILE}" 318 | 319 | echo "INFO: The transparent data encryption feature has been inactivated" 320 | 321 | return 0; 322 | } 323 | 324 | 325 | ################################################### 326 | # Main Process # 327 | ################################################### 328 | 329 | if [ $# -ne 1 ]; then 330 | echo "usage: sh bin/cipher_setup.sh POSTGRESQL_DIR" 331 | echo "Please specify PostgreSQL installed directory" 332 | exit 1 333 | fi 334 | 335 | echo "Transparent data encryption feature setup script" 336 | echo "Please select from the setup menu below" 337 | 338 | 339 | while [ 1 ] 340 | do 341 | echo 'Transparent data encryption feature setup menu' 342 | echo '1: activate the transparent data encryption feature' 343 | echo '2: inactivate the transparent data encryption feature' 344 | prompt="select menu [1 - 2] > " 345 | read -p "${prompt}" select 346 | 347 | case $select in 348 | 1) 349 | validate;break 350 | ;; 351 | 2) 352 | invalidate;break 353 | ;; 354 | *) 355 | echo "ERROR: Invalid menu number : $select" 356 | continue; 357 | ;; 358 | esac 359 | done 360 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/10: -------------------------------------------------------------------------------- 1 | tdeforpg -------------------------------------------------------------------------------- /SOURCES/data_encryption/95: -------------------------------------------------------------------------------- 1 | tdeforpg -------------------------------------------------------------------------------- /SOURCES/data_encryption/96: -------------------------------------------------------------------------------- 1 | tdeforpg -------------------------------------------------------------------------------- /SOURCES/data_encryption/makedencryption.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | #data_encryption module build script 3 | 4 | TDEVERSION=1.2.1.0 5 | CURR_PATH=`pwd` 6 | PGVERSION=$1 7 | SPATH=$2 8 | AESNI="pgcrypto-aes-ni" 9 | 10 | cd $PGVERSION 11 | CDIR=`pwd` 12 | 13 | rm -f Makefile 14 | cp Makefile.in Makefile 15 | 16 | #set path from Makefile if SPATH is not set 17 | if [ -z $SPATH ]; 18 | then 19 | SPATH=`cat Makefile |grep ^PGSQL_SRC_PATH|cut -f3 -d" "` 20 | fi 21 | 22 | PGCRYPTO_PATH=${SPATH}/contrib/pgcrypto 23 | 24 | ############ build pgcrypto ########### 25 | # prepare support aes-ni pgcrypto for PostgreSQL 9.6, 9.5 with back-port source 26 | if [ "$PGVERSION" -eq "96" \ 27 | -o "$PGVERSION" -eq "95" ]; then 28 | 29 | if [ -d ${PGCRYPTO_PATH}.bk ]; then 30 | # may be it was interrupted in previous time. Do nothing 31 | : 32 | else 33 | # backup original pgcrypto 34 | cp ${PGCRYPTO_PATH} ${PGCRYPTO_PATH}.bk -rf 35 | fi 36 | 37 | # if not already fixed 38 | if [ ! -f ${PGCRYPTO_PATH}/aes-ni-fixed ]; then 39 | # back-port 40 | cp ${CURR_PATH}/${AESNI}/openssl.c ${PGCRYPTO_PATH}/ -f 41 | cd ${PGCRYPTO_PATH} 42 | patch < ${CURR_PATH}/${AESNI}/pgp-encrypt.patch 43 | touch ${PGCRYPTO_PATH}/aes-ni-fixed 44 | fi 45 | fi 46 | 47 | # build pgcrypto 48 | cd ${PGCRYPTO_PATH} 49 | make clean 50 | rm -f libpgcrypto.so 51 | make 52 | cp -f pgcrypto.so ${CDIR}/libpgcrypto${PGVERSION}.so.${TDEVERSION} 53 | ldd pgcrypto.so | grep "libcrypto.so.10" 54 | if [ $? -eq 1 ]; then 55 | if [ "$PGVERSION" -ne "93" -a "$PGVERSION" -ne "94" ]; then 56 | echo "WARNING: not built with AES-NI. PostgreSQL must be configured with --with-openssl to support AES-NI."; 57 | fi 58 | fi 59 | 60 | cd ${CDIR} 61 | 62 | #build data_encryption 63 | make clean 64 | make PGSQL_SRC_PATH=${SPATH} 65 | mv data_encryption.so data_encryption${PGVERSION}.so.${TDEVERSION} 66 | 67 | # add debug link to data_encryption.so in release mode 68 | if [ -f data_encryption.debug ]; then 69 | mv data_encryption.debug data_encryption${PGVERSION}.debug.${TDEVERSION} 70 | objcopy --add-gnu-debuglink=data_encryption${PGVERSION}.debug.${TDEVERSION} data_encryption${PGVERSION}.so.${TDEVERSION} 71 | fi 72 | 73 | ldd data_encryption${PGVERSION}.so.${TDEVERSION} 74 | 75 | # move back the directory 76 | if [ "$PGVERSION" -eq "95" -o "$PGVERSION" -eq "96" ] && [ -d "${PGCRYPTO_PATH}.bk" ] 77 | then 78 | rm -rf ${PGCRYPTO_PATH}; 79 | mv ${PGCRYPTO_PATH}.bk ${PGCRYPTO_PATH}; 80 | fi 81 | 82 | if [ ! -f data_encryption${PGVERSION}.so.${TDEVERSION} ]; 83 | then 84 | echo "ERROR: cannot make data_encryption.so" 85 | exit 1; 86 | fi 87 | 88 | echo 89 | echo "INFO: data_encryption.so was made." 90 | echo 91 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/msvc_tools/Mkvcbuild.pm.10.diff: -------------------------------------------------------------------------------- 1 | --- Mkvcbuild.pm.orig 2018-02-27 07:10:46 +0900 2 | +++ Mkvcbuild.pm 2018-05-22 14:06:14 +0900 3 | @@ -46,7 +46,7 @@ 4 | 'ltree_plpython', 'pgcrypto', 5 | 'sepgsql', 'brin', 6 | 'test_extensions', 'test_pg_dump', 7 | - 'snapshot_too_old'); 8 | + 'snapshot_too_old', 'data_encryption'); 9 | 10 | # Set of variables for frontend modules 11 | my $frontend_defines = { 'initdb' => 'FRONTEND' }; 12 | @@ -469,6 +469,26 @@ 13 | closedir($D); 14 | } 15 | 16 | + ### TDEforPG build ### 17 | + ###################### 18 | + my $data_encryption = 19 | + $solution->AddProject('data_encryption', 'dll', 'data_encryption', 'contrib/data_encryption'); 20 | + # source files 21 | + $data_encryption->AddFiles( 22 | + 'contrib/data_encryption', 'data_encryption.c'); 23 | + # resource file 24 | + $data_encryption->AddFile('contrib/data_encryption/win32ver.rc'); 25 | + 26 | + $data_encryption->AddIncludeDir('src/include'); 27 | + $data_encryption->AddIncludeDir('contrib/pgcrypto'); 28 | + $data_encryption->AddIncludeDir('src/include/port/win32'); 29 | + $data_encryption->AddLibrary('Release/postgres/postgres.lib'); 30 | + $data_encryption->AddLibrary('Release/pgcrypto/pgcrypto.lib'); 31 | + $data_encryption->AddLibrary('ws2_32.lib'); 32 | + $data_encryption->AddReference($postgres, $pgcrypto); 33 | + 34 | + ###################### 35 | + 36 | # Build Perl and Python modules after contrib/ modules to satisfy some 37 | # dependencies with transform contrib modules, like hstore_plpython 38 | # ltree_plpython and hstore_plperl. 39 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/msvc_tools/Mkvcbuild.pm.95.diff: -------------------------------------------------------------------------------- 1 | --- Mkvcbuild.pm.orig 2018-02-27 22:08:52 +0900 2 | +++ Mkvcbuild.pm 2018-05-22 13:32:03 +0900 3 | @@ -42,7 +42,8 @@ 4 | 'seg' => [ 'contrib/seg/segscan.l', 'contrib/seg/segparse.y' ], }; 5 | my @contrib_excludes = ( 6 | 'commit_ts', 'hstore_plperl', 'hstore_plpython', 'intagg', 7 | - 'ltree_plpython', 'pgcrypto', 'sepgsql', 'brin'); 8 | + 'ltree_plpython', 'pgcrypto', 'sepgsql', 'brin', 9 | + 'data_encryption'); 10 | 11 | # Set of variables for frontend modules 12 | my $frontend_defines = { 'initdb' => 'FRONTEND' }; 13 | @@ -463,7 +464,26 @@ 14 | } 15 | closedir($D); 16 | } 17 | - 18 | + 19 | + ### TDEforPG build ### 20 | + ###################### 21 | + my $data_encryption = 22 | + $solution->AddProject('data_encryption', 'dll', 'data_encryption', 'contrib/data_encryption'); 23 | + # source files 24 | + $data_encryption->AddFiles( 25 | + 'contrib/data_encryption', 'data_encryption.c'); 26 | + # resource file 27 | + $data_encryption->AddFile('contrib/data_encryption/win32ver.rc'); 28 | + 29 | + $data_encryption->AddIncludeDir('src/include'); 30 | + $data_encryption->AddIncludeDir('contrib/pgcrypto'); 31 | + $data_encryption->AddIncludeDir('src/include/port/win32'); 32 | + $data_encryption->AddLibrary('Release/pgcrypto/pgcrypto.lib'); 33 | + $data_encryption->AddLibrary('ws2_32.lib'); 34 | + $data_encryption->AddReference($postgres, $pgcrypto); 35 | + 36 | + ###################### 37 | + 38 | # Build Perl and Python modules after contrib/ modules to satisfy some 39 | # dependencies with transform contrib modules, like hstore_plpython 40 | # ltree_plpython and hstore_plperl. 41 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/msvc_tools/Mkvcbuild.pm.96.diff: -------------------------------------------------------------------------------- 1 | --- Mkvcbuild.pm.orig 2018-02-27 07:13:40 +0900 2 | +++ Mkvcbuild.pm 2018-05-22 14:11:53 +0900 3 | @@ -47,7 +47,7 @@ 4 | 'ltree_plpython', 'pgcrypto', 5 | 'sepgsql', 'brin', 6 | 'test_extensions', 'test_pg_dump', 7 | - 'snapshot_too_old'); 8 | + 'snapshot_too_old', 'data_encryption'); 9 | 10 | # Set of variables for frontend modules 11 | my $frontend_defines = { 'initdb' => 'FRONTEND' }; 12 | @@ -471,7 +471,26 @@ 13 | } 14 | closedir($D); 15 | } 16 | - 17 | + 18 | + ### TDEforPG build ### 19 | + ###################### 20 | + my $data_encryption = 21 | + $solution->AddProject('data_encryption', 'dll', 'data_encryption', 'contrib/data_encryption'); 22 | + # source files 23 | + $data_encryption->AddFiles( 24 | + 'contrib/data_encryption', 'data_encryption.c'); 25 | + # resource file 26 | + $data_encryption->AddFile('contrib/data_encryption/win32ver.rc'); 27 | + 28 | + $data_encryption->AddIncludeDir('src/include'); 29 | + $data_encryption->AddIncludeDir('contrib/pgcrypto'); 30 | + $data_encryption->AddIncludeDir('src/include/port/win32'); 31 | + $data_encryption->AddLibrary('Release/pgcrypto/pgcrypto.lib'); 32 | + $data_encryption->AddLibrary('ws2_32.lib'); 33 | + $data_encryption->AddReference($postgres, $pgcrypto); 34 | + 35 | + ###################### 36 | + 37 | # Build Perl and Python modules after contrib/ modules to satisfy some 38 | # dependencies with transform contrib modules, like hstore_plpython 39 | # ltree_plpython and hstore_plperl. 40 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/msvc_tools/config.pl: -------------------------------------------------------------------------------- 1 | # Configuration arguments for vcbuild. 2 | use strict; 3 | use warnings; 4 | 5 | our $config = { 6 | asserts => 0, # --enable-cassert 7 | # integer_datetimes=>1, # --enable-integer-datetimes - on is now default 8 | # float4byval=>1, # --disable-float4-byval, on by default 9 | 10 | # float8byval=> $platformbits == 64, # --disable-float8-byval, 11 | # off by default on 32 bit platforms, on by default on 64 bit platforms 12 | 13 | # blocksize => 8, # --with-blocksize, 8kB by default 14 | # wal_blocksize => 8, # --with-wal-blocksize, 8kB by default 15 | # wal_segsize => 16, # --with-wal-segsize, 16MB by default 16 | ldap => 1, # --with-ldap 17 | extraver => undef, # --with-extra-version= 18 | gss => undef, # --with-gssapi= 19 | nls => undef, # --enable-nls= 20 | tap_tests => undef, # --enable-tap-tests 21 | tcl => undef, # --with-tls= 22 | perl => undef, # --with-perl 23 | python => undef, # --with-python= 24 | openssl => 'C:\OpenSSL-Win64', # --with-openssl= 25 | uuid => undef, # --with-ossp-uuid 26 | xml => undef, # --with-libxml= 27 | xslt => undef, # --with-libxslt= 28 | iconv => undef, # (not in configure, path to iconv) 29 | zlib => undef # --with-zlib= 30 | }; 31 | 32 | 1; 33 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/msvc_tools/win32ver.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pg_config.h" 3 | 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 1,2,1,0 6 | PRODUCTVERSION 1,2,1,0 7 | FILEFLAGSMASK 0x17L 8 | FILEFLAGS 0x0L 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE 0x0L 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "000004b0" 16 | BEGIN 17 | VALUE "CompanyName", "NEC Corporation" 18 | VALUE "FileDescription", "TDEforPG Free Edition DLL" 19 | VALUE "FileVersion", "1.2.1.0" 20 | VALUE "LegalCopyright", "Copyright (C) 2015-2018 NEC Corporation. All rights reserved." 21 | VALUE "ProductName", "Transparent Data Encryption for PostgreSQL Free Edition" 22 | VALUE "ProductVersion", "1.2.1.0" 23 | END 24 | END 25 | BLOCK "VarFileInfo" 26 | BEGIN 27 | VALUE "Translation", 0x0, 1200 28 | END 29 | END 30 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/pgcrypto-aes-ni/openssl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * openssl.c 3 | * Wrapper for OpenSSL library. 4 | * 5 | * Copyright (c) 2001 Marko Kreen 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * contrib/pgcrypto/openssl.c 30 | */ 31 | 32 | #include "postgres.h" 33 | 34 | #include "px.h" 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "utils/memutils.h" 41 | #include "utils/resowner.h" 42 | 43 | /* 44 | * Max lengths we might want to handle. 45 | */ 46 | #define MAX_KEY (512/8) 47 | #define MAX_IV (128/8) 48 | 49 | /* 50 | * Hashes 51 | */ 52 | 53 | /* 54 | * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest 55 | * objects in a linked list, allocated in TopMemoryContext. We use the 56 | * ResourceOwner mechanism to free them on abort. 57 | */ 58 | typedef struct OSSLDigest 59 | { 60 | const EVP_MD *algo; 61 | EVP_MD_CTX *ctx; 62 | 63 | ResourceOwner owner; 64 | struct OSSLDigest *next; 65 | struct OSSLDigest *prev; 66 | } OSSLDigest; 67 | 68 | static OSSLDigest *open_digests = NULL; 69 | static bool digest_resowner_callback_registered = false; 70 | 71 | static void 72 | free_openssl_digest(OSSLDigest *digest) 73 | { 74 | EVP_MD_CTX_destroy(digest->ctx); 75 | if (digest->prev) 76 | digest->prev->next = digest->next; 77 | else 78 | open_digests = digest->next; 79 | if (digest->next) 80 | digest->next->prev = digest->prev; 81 | pfree(digest); 82 | } 83 | 84 | /* 85 | * Close any open OpenSSL handles on abort. 86 | */ 87 | static void 88 | digest_free_callback(ResourceReleasePhase phase, 89 | bool isCommit, 90 | bool isTopLevel, 91 | void *arg) 92 | { 93 | OSSLDigest *curr; 94 | OSSLDigest *next; 95 | 96 | if (phase != RESOURCE_RELEASE_AFTER_LOCKS) 97 | return; 98 | 99 | next = open_digests; 100 | while (next) 101 | { 102 | curr = next; 103 | next = curr->next; 104 | 105 | if (curr->owner == CurrentResourceOwner) 106 | { 107 | if (isCommit) 108 | elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr); 109 | free_openssl_digest(curr); 110 | } 111 | } 112 | } 113 | 114 | static unsigned 115 | digest_result_size(PX_MD *h) 116 | { 117 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 118 | 119 | return EVP_MD_CTX_size(digest->ctx); 120 | } 121 | 122 | static unsigned 123 | digest_block_size(PX_MD *h) 124 | { 125 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 126 | 127 | return EVP_MD_CTX_block_size(digest->ctx); 128 | } 129 | 130 | static void 131 | digest_reset(PX_MD *h) 132 | { 133 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 134 | 135 | EVP_DigestInit_ex(digest->ctx, digest->algo, NULL); 136 | } 137 | 138 | static void 139 | digest_update(PX_MD *h, const uint8 *data, unsigned dlen) 140 | { 141 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 142 | 143 | EVP_DigestUpdate(digest->ctx, data, dlen); 144 | } 145 | 146 | static void 147 | digest_finish(PX_MD *h, uint8 *dst) 148 | { 149 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 150 | 151 | EVP_DigestFinal_ex(digest->ctx, dst, NULL); 152 | } 153 | 154 | static void 155 | digest_free(PX_MD *h) 156 | { 157 | OSSLDigest *digest = (OSSLDigest *) h->p.ptr; 158 | 159 | free_openssl_digest(digest); 160 | px_free(h); 161 | } 162 | 163 | static int px_openssl_initialized = 0; 164 | 165 | /* PUBLIC functions */ 166 | 167 | int 168 | px_find_digest(const char *name, PX_MD **res) 169 | { 170 | const EVP_MD *md; 171 | EVP_MD_CTX *ctx; 172 | PX_MD *h; 173 | OSSLDigest *digest; 174 | 175 | if (!px_openssl_initialized) 176 | { 177 | px_openssl_initialized = 1; 178 | OpenSSL_add_all_algorithms(); 179 | } 180 | 181 | if (!digest_resowner_callback_registered) 182 | { 183 | RegisterResourceReleaseCallback(digest_free_callback, NULL); 184 | digest_resowner_callback_registered = true; 185 | } 186 | 187 | md = EVP_get_digestbyname(name); 188 | if (md == NULL) 189 | return PXE_NO_HASH; 190 | 191 | /* 192 | * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object. 193 | * The order is crucial, to make sure we don't leak anything on 194 | * out-of-memory or other error. 195 | */ 196 | digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest)); 197 | 198 | ctx = EVP_MD_CTX_create(); 199 | if (!ctx) 200 | { 201 | pfree(digest); 202 | return -1; 203 | } 204 | if (EVP_DigestInit_ex(ctx, md, NULL) == 0) 205 | { 206 | pfree(digest); 207 | return -1; 208 | } 209 | 210 | digest->algo = md; 211 | digest->ctx = ctx; 212 | digest->owner = CurrentResourceOwner; 213 | digest->next = open_digests; 214 | digest->prev = NULL; 215 | open_digests = digest; 216 | 217 | /* The PX_MD object is allocated in the current memory context. */ 218 | h = px_alloc(sizeof(*h)); 219 | h->result_size = digest_result_size; 220 | h->block_size = digest_block_size; 221 | h->reset = digest_reset; 222 | h->update = digest_update; 223 | h->finish = digest_finish; 224 | h->free = digest_free; 225 | h->p.ptr = (void *) digest; 226 | 227 | *res = h; 228 | return 0; 229 | } 230 | 231 | /* 232 | * Ciphers 233 | * 234 | * We use OpenSSL's EVP* family of functions for these. 235 | */ 236 | 237 | /* 238 | * prototype for the EVP functions that return an algorithm, e.g. 239 | * EVP_aes_128_cbc(). 240 | */ 241 | typedef const EVP_CIPHER *(*ossl_EVP_cipher_func)(void); 242 | 243 | /* 244 | * ossl_cipher contains the static information about each cipher. 245 | */ 246 | struct ossl_cipher 247 | { 248 | int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv); 249 | ossl_EVP_cipher_func cipher_func; 250 | int block_size; 251 | int max_key_size; 252 | }; 253 | 254 | /* 255 | * OSSLCipher contains the state for using a cipher. A separate OSSLCipher 256 | * object is allocated in each px_find_cipher() call. 257 | * 258 | * To make sure we don't leak OpenSSL handles on abort, we keep OSSLCipher 259 | * objects in a linked list, allocated in TopMemoryContext. We use the 260 | * ResourceOwner mechanism to free them on abort. 261 | */ 262 | typedef struct OSSLCipher 263 | { 264 | EVP_CIPHER_CTX *evp_ctx; 265 | const EVP_CIPHER *evp_ciph; 266 | uint8 key[MAX_KEY]; 267 | uint8 iv[MAX_IV]; 268 | unsigned klen; 269 | unsigned init; 270 | const struct ossl_cipher *ciph; 271 | 272 | ResourceOwner owner; 273 | struct OSSLCipher *next; 274 | struct OSSLCipher *prev; 275 | } OSSLCipher; 276 | 277 | static OSSLCipher *open_ciphers = NULL; 278 | static bool cipher_resowner_callback_registered = false; 279 | 280 | static void 281 | free_openssl_cipher(OSSLCipher *od) 282 | { 283 | EVP_CIPHER_CTX_free(od->evp_ctx); 284 | if (od->prev) 285 | od->prev->next = od->next; 286 | else 287 | open_ciphers = od->next; 288 | if (od->next) 289 | od->next->prev = od->prev; 290 | pfree(od); 291 | } 292 | 293 | /* 294 | * Close any open OpenSSL cipher handles on abort. 295 | */ 296 | static void 297 | cipher_free_callback(ResourceReleasePhase phase, 298 | bool isCommit, 299 | bool isTopLevel, 300 | void *arg) 301 | { 302 | OSSLCipher *curr; 303 | OSSLCipher *next; 304 | 305 | if (phase != RESOURCE_RELEASE_AFTER_LOCKS) 306 | return; 307 | 308 | next = open_ciphers; 309 | while (next) 310 | { 311 | curr = next; 312 | next = curr->next; 313 | 314 | if (curr->owner == CurrentResourceOwner) 315 | { 316 | if (isCommit) 317 | elog(WARNING, "pgcrypto cipher reference leak: cipher %p still referenced", curr); 318 | free_openssl_cipher(curr); 319 | } 320 | } 321 | } 322 | 323 | /* Common routines for all algorithms */ 324 | 325 | static unsigned 326 | gen_ossl_block_size(PX_Cipher *c) 327 | { 328 | OSSLCipher *od = (OSSLCipher *) c->ptr; 329 | 330 | return od->ciph->block_size; 331 | } 332 | 333 | static unsigned 334 | gen_ossl_key_size(PX_Cipher *c) 335 | { 336 | OSSLCipher *od = (OSSLCipher *) c->ptr; 337 | 338 | return od->ciph->max_key_size; 339 | } 340 | 341 | static unsigned 342 | gen_ossl_iv_size(PX_Cipher *c) 343 | { 344 | unsigned ivlen; 345 | OSSLCipher *od = (OSSLCipher *) c->ptr; 346 | 347 | ivlen = od->ciph->block_size; 348 | return ivlen; 349 | } 350 | 351 | static void 352 | gen_ossl_free(PX_Cipher *c) 353 | { 354 | OSSLCipher *od = (OSSLCipher *) c->ptr; 355 | 356 | free_openssl_cipher(od); 357 | px_free(c); 358 | } 359 | 360 | static int 361 | gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, 362 | uint8 *res) 363 | { 364 | OSSLCipher *od = c->ptr; 365 | int outlen; 366 | 367 | if (!od->init) 368 | { 369 | if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL)) 370 | return PXE_CIPHER_INIT; 371 | if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen)) 372 | return PXE_CIPHER_INIT; 373 | if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv)) 374 | return PXE_CIPHER_INIT; 375 | od->init = true; 376 | } 377 | 378 | if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen)) 379 | return PXE_DECRYPT_FAILED; 380 | 381 | return 0; 382 | } 383 | 384 | static int 385 | gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, 386 | uint8 *res) 387 | { 388 | OSSLCipher *od = c->ptr; 389 | int outlen; 390 | 391 | if (!od->init) 392 | { 393 | if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL)) 394 | return PXE_CIPHER_INIT; 395 | if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen)) 396 | return PXE_CIPHER_INIT; 397 | if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv)) 398 | return PXE_CIPHER_INIT; 399 | od->init = true; 400 | } 401 | 402 | if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen)) 403 | return PXE_ERR_GENERIC; 404 | 405 | return 0; 406 | } 407 | 408 | /* Blowfish */ 409 | 410 | /* 411 | * Check if strong crypto is supported. Some openssl installations 412 | * support only short keys and unfortunately BF_set_key does not return any 413 | * error value. This function tests if is possible to use strong key. 414 | */ 415 | static int 416 | bf_check_supported_key_len(void) 417 | { 418 | static const uint8 key[56] = { 419 | 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69, 420 | 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33, 421 | 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 422 | 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, 423 | 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff, 424 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 425 | }; 426 | 427 | static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; 428 | static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53}; 429 | uint8 out[8]; 430 | EVP_CIPHER_CTX *evp_ctx; 431 | int outlen; 432 | int status = 0; 433 | 434 | /* encrypt with 448bits key and verify output */ 435 | evp_ctx = EVP_CIPHER_CTX_new(); 436 | if (!evp_ctx) 437 | return 0; 438 | if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL)) 439 | goto leave; 440 | if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56)) 441 | goto leave; 442 | if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL)) 443 | goto leave; 444 | 445 | if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8)) 446 | goto leave; 447 | 448 | if (memcmp(out, res, 8) != 0) 449 | goto leave; /* Output does not match -> strong cipher is 450 | * not supported */ 451 | status = 1; 452 | 453 | leave: 454 | EVP_CIPHER_CTX_free(evp_ctx); 455 | return status; 456 | } 457 | 458 | static int 459 | bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 460 | { 461 | OSSLCipher *od = c->ptr; 462 | unsigned bs = gen_ossl_block_size(c); 463 | static int bf_is_strong = -1; 464 | 465 | /* 466 | * Test if key len is supported. BF_set_key silently cut large keys and it 467 | * could be a problem when user transfer crypted data from one server to 468 | * another. 469 | */ 470 | 471 | if (bf_is_strong == -1) 472 | bf_is_strong = bf_check_supported_key_len(); 473 | 474 | if (!bf_is_strong && klen > 16) 475 | return PXE_KEY_TOO_BIG; 476 | 477 | /* Key len is supported. We can use it. */ 478 | od->klen = klen; 479 | memcpy(od->key, key, klen); 480 | 481 | if (iv) 482 | memcpy(od->iv, iv, bs); 483 | else 484 | memset(od->iv, 0, bs); 485 | return 0; 486 | } 487 | 488 | /* DES */ 489 | 490 | static int 491 | ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 492 | { 493 | OSSLCipher *od = c->ptr; 494 | unsigned bs = gen_ossl_block_size(c); 495 | 496 | od->klen = 8; 497 | memset(od->key, 0, 8); 498 | memcpy(od->key, key, klen > 8 ? 8 : klen); 499 | 500 | if (iv) 501 | memcpy(od->iv, iv, bs); 502 | else 503 | memset(od->iv, 0, bs); 504 | return 0; 505 | } 506 | 507 | /* DES3 */ 508 | 509 | static int 510 | ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 511 | { 512 | OSSLCipher *od = c->ptr; 513 | unsigned bs = gen_ossl_block_size(c); 514 | 515 | od->klen = 24; 516 | memset(od->key, 0, 24); 517 | memcpy(od->key, key, klen > 24 ? 24 : klen); 518 | 519 | if (iv) 520 | memcpy(od->iv, iv, bs); 521 | else 522 | memset(od->iv, 0, bs); 523 | return 0; 524 | } 525 | 526 | /* CAST5 */ 527 | 528 | static int 529 | ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 530 | { 531 | OSSLCipher *od = c->ptr; 532 | unsigned bs = gen_ossl_block_size(c); 533 | 534 | od->klen = klen; 535 | memcpy(od->key, key, klen); 536 | 537 | if (iv) 538 | memcpy(od->iv, iv, bs); 539 | else 540 | memset(od->iv, 0, bs); 541 | return 0; 542 | } 543 | 544 | /* AES */ 545 | 546 | static int 547 | ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 548 | { 549 | OSSLCipher *od = c->ptr; 550 | unsigned bs = gen_ossl_block_size(c); 551 | 552 | if (klen <= 128 / 8) 553 | od->klen = 128 / 8; 554 | else if (klen <= 192 / 8) 555 | od->klen = 192 / 8; 556 | else if (klen <= 256 / 8) 557 | od->klen = 256 / 8; 558 | else 559 | return PXE_KEY_TOO_BIG; 560 | 561 | memcpy(od->key, key, klen); 562 | 563 | if (iv) 564 | memcpy(od->iv, iv, bs); 565 | else 566 | memset(od->iv, 0, bs); 567 | 568 | return 0; 569 | } 570 | 571 | static int 572 | ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 573 | { 574 | OSSLCipher *od = c->ptr; 575 | int err; 576 | 577 | err = ossl_aes_init(c, key, klen, iv); 578 | if (err) 579 | return err; 580 | 581 | switch (od->klen) 582 | { 583 | case 128 / 8: 584 | od->evp_ciph = EVP_aes_128_ecb(); 585 | break; 586 | case 192 / 8: 587 | od->evp_ciph = EVP_aes_192_ecb(); 588 | break; 589 | case 256 / 8: 590 | od->evp_ciph = EVP_aes_256_ecb(); 591 | break; 592 | default: 593 | /* shouldn't happen */ 594 | err = PXE_CIPHER_INIT; 595 | break; 596 | } 597 | 598 | return err; 599 | } 600 | 601 | static int 602 | ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) 603 | { 604 | OSSLCipher *od = c->ptr; 605 | int err; 606 | 607 | err = ossl_aes_init(c, key, klen, iv); 608 | if (err) 609 | return err; 610 | 611 | switch (od->klen) 612 | { 613 | case 128 / 8: 614 | od->evp_ciph = EVP_aes_128_cbc(); 615 | break; 616 | case 192 / 8: 617 | od->evp_ciph = EVP_aes_192_cbc(); 618 | break; 619 | case 256 / 8: 620 | od->evp_ciph = EVP_aes_256_cbc(); 621 | break; 622 | default: 623 | /* shouldn't happen */ 624 | err = PXE_CIPHER_INIT; 625 | break; 626 | } 627 | 628 | return err; 629 | } 630 | 631 | /* 632 | * aliases 633 | */ 634 | 635 | static PX_Alias ossl_aliases[] = { 636 | {"bf", "bf-cbc"}, 637 | {"blowfish", "bf-cbc"}, 638 | {"blowfish-cbc", "bf-cbc"}, 639 | {"blowfish-ecb", "bf-ecb"}, 640 | {"blowfish-cfb", "bf-cfb"}, 641 | {"des", "des-cbc"}, 642 | {"3des", "des3-cbc"}, 643 | {"3des-ecb", "des3-ecb"}, 644 | {"3des-cbc", "des3-cbc"}, 645 | {"cast5", "cast5-cbc"}, 646 | {"aes", "aes-cbc"}, 647 | {"rijndael", "aes-cbc"}, 648 | {"rijndael-cbc", "aes-cbc"}, 649 | {"rijndael-ecb", "aes-ecb"}, 650 | {NULL} 651 | }; 652 | 653 | static const struct ossl_cipher ossl_bf_cbc = { 654 | bf_init, 655 | EVP_bf_cbc, 656 | 64 / 8, 448 / 8 657 | }; 658 | 659 | static const struct ossl_cipher ossl_bf_ecb = { 660 | bf_init, 661 | EVP_bf_ecb, 662 | 64 / 8, 448 / 8 663 | }; 664 | 665 | static const struct ossl_cipher ossl_bf_cfb = { 666 | bf_init, 667 | EVP_bf_cfb, 668 | 64 / 8, 448 / 8 669 | }; 670 | 671 | static const struct ossl_cipher ossl_des_ecb = { 672 | ossl_des_init, 673 | EVP_des_ecb, 674 | 64 / 8, 64 / 8 675 | }; 676 | 677 | static const struct ossl_cipher ossl_des_cbc = { 678 | ossl_des_init, 679 | EVP_des_cbc, 680 | 64 / 8, 64 / 8 681 | }; 682 | 683 | static const struct ossl_cipher ossl_des3_ecb = { 684 | ossl_des3_init, 685 | EVP_des_ede3_ecb, 686 | 64 / 8, 192 / 8 687 | }; 688 | 689 | static const struct ossl_cipher ossl_des3_cbc = { 690 | ossl_des3_init, 691 | EVP_des_ede3_cbc, 692 | 64 / 8, 192 / 8 693 | }; 694 | 695 | static const struct ossl_cipher ossl_cast_ecb = { 696 | ossl_cast_init, 697 | EVP_cast5_ecb, 698 | 64 / 8, 128 / 8 699 | }; 700 | 701 | static const struct ossl_cipher ossl_cast_cbc = { 702 | ossl_cast_init, 703 | EVP_cast5_cbc, 704 | 64 / 8, 128 / 8 705 | }; 706 | 707 | static const struct ossl_cipher ossl_aes_ecb = { 708 | ossl_aes_ecb_init, 709 | NULL, /* EVP_aes_XXX_ecb(), determined in init function */ 710 | 128 / 8, 256 / 8 711 | }; 712 | 713 | static const struct ossl_cipher ossl_aes_cbc = { 714 | ossl_aes_cbc_init, 715 | NULL, /* EVP_aes_XXX_cbc(), determined in init function */ 716 | 128 / 8, 256 / 8 717 | }; 718 | 719 | /* 720 | * Special handlers 721 | */ 722 | struct ossl_cipher_lookup 723 | { 724 | const char *name; 725 | const struct ossl_cipher *ciph; 726 | }; 727 | 728 | static const struct ossl_cipher_lookup ossl_cipher_types[] = { 729 | {"bf-cbc", &ossl_bf_cbc}, 730 | {"bf-ecb", &ossl_bf_ecb}, 731 | {"bf-cfb", &ossl_bf_cfb}, 732 | {"des-ecb", &ossl_des_ecb}, 733 | {"des-cbc", &ossl_des_cbc}, 734 | {"des3-ecb", &ossl_des3_ecb}, 735 | {"des3-cbc", &ossl_des3_cbc}, 736 | {"cast5-ecb", &ossl_cast_ecb}, 737 | {"cast5-cbc", &ossl_cast_cbc}, 738 | {"aes-ecb", &ossl_aes_ecb}, 739 | {"aes-cbc", &ossl_aes_cbc}, 740 | {NULL} 741 | }; 742 | 743 | /* PUBLIC functions */ 744 | 745 | int 746 | px_find_cipher(const char *name, PX_Cipher **res) 747 | { 748 | const struct ossl_cipher_lookup *i; 749 | PX_Cipher *c = NULL; 750 | EVP_CIPHER_CTX *ctx; 751 | OSSLCipher *od; 752 | 753 | name = px_resolve_alias(ossl_aliases, name); 754 | for (i = ossl_cipher_types; i->name; i++) 755 | if (strcmp(i->name, name) == 0) 756 | break; 757 | if (i->name == NULL) 758 | return PXE_NO_CIPHER; 759 | 760 | if (!cipher_resowner_callback_registered) 761 | { 762 | RegisterResourceReleaseCallback(cipher_free_callback, NULL); 763 | cipher_resowner_callback_registered = true; 764 | } 765 | 766 | /* 767 | * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher. 768 | * The order is crucial, to make sure we don't leak anything on 769 | * out-of-memory or other error. 770 | */ 771 | od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od)); 772 | od->ciph = i->ciph; 773 | 774 | /* Allocate an EVP_CIPHER_CTX object. */ 775 | ctx = EVP_CIPHER_CTX_new(); 776 | if (!ctx) 777 | { 778 | pfree(od); 779 | return PXE_CIPHER_INIT; 780 | } 781 | 782 | od->evp_ctx = ctx; 783 | od->owner = CurrentResourceOwner; 784 | od->next = open_ciphers; 785 | od->prev = NULL; 786 | open_ciphers = od; 787 | 788 | if (i->ciph->cipher_func) 789 | od->evp_ciph = i->ciph->cipher_func(); 790 | 791 | /* The PX_Cipher is allocated in current memory context */ 792 | c = px_alloc(sizeof(*c)); 793 | c->block_size = gen_ossl_block_size; 794 | c->key_size = gen_ossl_key_size; 795 | c->iv_size = gen_ossl_iv_size; 796 | c->free = gen_ossl_free; 797 | c->init = od->ciph->init; 798 | c->encrypt = gen_ossl_encrypt; 799 | c->decrypt = gen_ossl_decrypt; 800 | c->ptr = od; 801 | 802 | *res = c; 803 | return 0; 804 | } 805 | 806 | 807 | static int openssl_random_init = 0; 808 | 809 | /* 810 | * OpenSSL random should re-feeded occasionally. From /dev/urandom 811 | * preferably. 812 | */ 813 | static void 814 | init_openssl_rand(void) 815 | { 816 | if (RAND_get_rand_method() == NULL) 817 | { 818 | #ifdef HAVE_RAND_OPENSSL 819 | RAND_set_rand_method(RAND_OpenSSL()); 820 | #else 821 | RAND_set_rand_method(RAND_SSLeay()); 822 | #endif 823 | } 824 | openssl_random_init = 1; 825 | } 826 | 827 | int 828 | px_get_random_bytes(uint8 *dst, unsigned count) 829 | { 830 | int res; 831 | 832 | if (!openssl_random_init) 833 | init_openssl_rand(); 834 | 835 | res = RAND_bytes(dst, count); 836 | if (res == 1) 837 | return count; 838 | 839 | return PXE_OSSL_RAND_ERROR; 840 | } 841 | 842 | int 843 | px_add_entropy(const uint8 *data, unsigned count) 844 | { 845 | /* 846 | * estimate 0 bits 847 | */ 848 | RAND_add(data, count, 0); 849 | return 0; 850 | } 851 | 852 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/pgcrypto-aes-ni/pgp-encrypt.patch: -------------------------------------------------------------------------------- 1 | --- /home/bocap/src/tar/postgresql-9.6.1/contrib/pgcrypto/pgp-encrypt.c 2016-10-25 05:08:51.000000000 +0900 2 | +++ pgp-encrypt.c 2017-09-09 09:54:50.084723849 +0900 3 | @@ -217,6 +217,8 @@ 4 | { 5 | struct EncStat *st = priv; 6 | 7 | + if (st->ciph) 8 | + pgp_cfb_free(st->ciph); 9 | px_memset(st, 0, sizeof(*st)); 10 | px_free(st); 11 | } 12 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/tdeforpg/Makefile.in: -------------------------------------------------------------------------------- 1 | 2 | PGSQL_SRC_PATH ?= 3 | PGSQL_INCLUDE_PATH ?= $(PGSQL_SRC_PATH)/src/include 4 | PGSQL_LIBRARY_PATH ?= $(PGSQL_SRC_PATH)/contrib/pgcrypto 5 | export PGSQL_SRC_PATH 6 | export PGSQL_INCLUDE_PATH 7 | export PGSQL_LIBRARY_PATH 8 | 9 | BINARY = data_encryption.so 10 | OBJS = data_encryption.o 11 | 12 | CC = /usr/bin/gcc 13 | ifeq ($(debug),yes) 14 | CFLAGS = -c -Wall -O0 -ggdb $(DEBUG) -fPIC 15 | else 16 | CFLAGS = -c -Wall -ggdb -O3 -fPIC 17 | endif 18 | 19 | LFLAGS = -L$(PGSQL_LIBRARY_PATH) 20 | LINKER = -lpgcrypto -Wl,-rpath,'$(PGSQL_LIBRARY_PATH)' 21 | IFLAGS = -I$(PGSQL_INCLUDE_PATH) -I$(PGSQL_LIBRARY_PATH) 22 | 23 | all: $(BINARY) 24 | 25 | $(BINARY): $(OBJS) 26 | $(CC) -shared -o $(BINARY) $(OBJS) $(LFLAGS) $(LINKER) 27 | 28 | # remove unnecessary info from binary # 29 | ifneq ($(debug),yes) 30 | objcopy --only-keep-debug data_encryption.so data_encryption.debug 31 | strip --strip-debug data_encryption.so 32 | strip --strip-unneeded data_encryption.so 33 | endif 34 | ######################################## 35 | 36 | %.o: %.c 37 | $(CC) $(CFLAGS) $(IFLAGS) $< 38 | 39 | clean: 40 | rm -f $(BINARY) $(OBJS) *debug* 41 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/tdeforpg/data_encryption.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Transparent Data Encryption for PostgreSQL Free Edition 3 | * 4 | * Copyright (c) 2015 NEC Corporation 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #define KEY_HASH_TABLE_NAME "key_hash_table" 21 | 22 | /* structure for maintain encryption key information */ 23 | typedef struct { 24 | bytea *key; /* encryption key */ 25 | text *algorithm; /* encryption algorithm */ 26 | }key_info; 27 | 28 | #if PG_VERSION_NUM >= 100000 29 | /* Need to define these 2 functions from PostgreSQL 10 */ 30 | Datum pg_encrypt(PG_FUNCTION_ARGS); 31 | Datum pg_decrypt(PG_FUNCTION_ARGS); 32 | #endif 33 | 34 | bytea* pgtde_encrypt(bytea* input_data); 35 | Datum pgtde_decrypt(key_info* entry, bytea* encrypted_data); 36 | bytea* add_header_to_result(bytea* encrypted_data); 37 | bytea* remove_header_from_inputdata(bytea* input_data); 38 | bool cmp_binary(bytea* barg1, bytea* barg2); 39 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/win_build.bat: -------------------------------------------------------------------------------- 1 | SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 2 | 3 | REM ### TDEforPG Windows builder ### 4 | REM %1 : PostgreSQL Major Version (95 96 10 11 ...) 5 | REM %2 : PostgreSQL Source Directory 6 | 7 | IF NOT EXIST "tdeforpg\data_encryption.c" EXIT /B 255 8 | IF NOT EXIST "msvc_tools\Mkvcbuild.pm.%1.diff" EXIT /B 255 9 | 10 | FOR /F "usebackq tokens=*" %%i in (`CD`) DO SET BOOT_DIR=%%i 11 | SET PGTDE_SRC=%BOOT_DIR% 12 | 13 | SET MINGW_BIN=C:\MINGW\MSYS\1.0\BIN 14 | IF NOT EXIST "%MINGW_BIN%\PATCH.EXE" EXIT /B 255 15 | 16 | SET POSTGRES_MAJOR_VER=%1 17 | 18 | SET PGSRC_ROOT=%2 19 | SET PGSRC_CONTRIB=%PGSRC_ROOT%\contrib 20 | SET PGSRC=%PGSRC_ROOT%\src\tools\msvc 21 | 22 | REM ##### Copy suitable directory under "data_encryption" to PostgreSQL contrib 23 | CD /D "%PGSRC_CONTRIB%" 24 | IF EXIST data_encryption RD /Q /S data_encryption\ 25 | XCOPY /Y /F /I "%PGTDE_SRC%\tdeforpg" data_encryption 26 | COPY /Y "%PGTDE_SRC%\msvc_tools\win32ver.rc" data_encryption\ 27 | REM ##### Windows build need Makefile to work 28 | COPY /Y data_encryption\Makefile.in data_encryption\Makefile 29 | 30 | REM ##### Patch Mkvcbuild.pm to build TDEforPG ##### 31 | CD /D "%PGSRC_ROOT%\src\tools\msvc" 32 | COPY /Y Mkvcbuild.pm Mkvcbuild.pm.orig 33 | "%MINGW_BIN%\PATCH.EXE" -p0 -i "%PGTDE_SRC%\msvc_tools\Mkvcbuild.pm.%POSTGRES_MAJOR_VER%.diff" 34 | 35 | REM ##### Patch to pgcrypto for AES-NI ##### 36 | IF %POSTGRES_MAJOR_VER%==95 ( 37 | CALL :patch_now 38 | IF NOT !ERRORLEVEL!==0 EXIT /B !ERRORLEVEL! 39 | ) ELSE IF %POSTGRES_MAJOR_VER%==96 ( 40 | CALL :patch_now 41 | IF NOT !ERRORLEVEL!==0 EXIT /B !ERRORLEVEL! 42 | ) 43 | 44 | REM ##### Delete old build ##### 45 | CD /D "%PGSRC_ROOT%" 46 | IF EXIST Release ( RD /Q /S Release\ ) ELSE (ECHO Release directory is not found.) 47 | 48 | REM ##### Build NOW! ##### 49 | cd /D "%PGSRC%" 50 | CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 51 | CALL build.bat 52 | EXIT /B %ERRORLEVEL% 53 | 54 | 55 | :patch_now 56 | CD /D %PGSRC_CONTRIB%\pgcrypto 57 | COPY /Y openssl.c openssl.c.orig 58 | COPY /Y "%PGTDE_SRC%\pgcrypto-aes-ni\openssl.c" .\ 59 | IF NOT %ERRORLEVEL%==0 EXIT /B 255 60 | 61 | COPY /Y pgp-encrypt.c pgp-encrypt.c.orig 62 | "%MINGW_BIN%\PATCH.EXE" -p0 -i "%PGTDE_SRC%\pgcrypto-aes-ni\pgp-encrypt.patch" 63 | IF NOT %ERRORLEVEL%==0 EXIT /B 255 64 | EXIT /B 0 65 | -------------------------------------------------------------------------------- /SOURCES/data_encryption/win_fe_build_procedure.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/SOURCES/data_encryption/win_fe_build_procedure.txt -------------------------------------------------------------------------------- /SOURCES/lib/init/cipher_definition.sql: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------* 2 | * cipher_key_definition 3 | * 4 | * define type, function, index end etc for TDE. 5 | *------------------------------------------------------------*/ 6 | 7 | SET search_path TO public; 8 | SET check_function_bodies TO off; 9 | 10 | 11 | /* define a new procedural language */ 12 | /* CREATE TRUSTED LANGUAGE 'plpgsql' HANDLER language_handler_in;*/ 13 | 14 | /* drop if encrypted data types are already exist */ 15 | --DROP TYPE IF EXISTS encrypt_text CASCADE; 16 | --DROP TYPE IF EXISTS encrypt_bytea CASCADE; 17 | 18 | /* create encrypted data types */ 19 | CREATE TYPE encrypt_text; 20 | CREATE TYPE encrypt_bytea; 21 | 22 | /* define input function of encrypted text type */ 23 | CREATE FUNCTION 24 | enctext_in(cstring) 25 | RETURNS 26 | encrypt_text 27 | AS 28 | '/usr/lib64/data_encryption.so','enctext_in' 29 | LANGUAGE C STABLE STRICT; 30 | 31 | /* define output function of encrypted text type */ 32 | CREATE FUNCTION 33 | enctext_out(encrypt_text) 34 | RETURNS 35 | cstring 36 | AS 37 | '/usr/lib64/data_encryption.so','enctext_out' 38 | LANGUAGE C STABLE STRICT; 39 | 40 | /* define recv function of encrypted text type */ 41 | CREATE FUNCTION 42 | enctext_recv(internal) 43 | RETURNS 44 | encrypt_text 45 | AS 46 | '/usr/lib64/data_encryption.so','encrecv' 47 | LANGUAGE C IMMUTABLE STRICT; 48 | 49 | /* define send function of encrypted text type */ 50 | CREATE FUNCTION 51 | enctext_send(encrypt_text) 52 | RETURNS 53 | bytea 54 | AS 55 | '/usr/lib64/data_encryption.so','encsend' 56 | LANGUAGE C IMMUTABLE STRICT; 57 | 58 | /* define input function of encrypted binary type */ 59 | CREATE FUNCTION 60 | encbytea_in(cstring) 61 | RETURNS 62 | encrypt_bytea 63 | AS 64 | '/usr/lib64/data_encryption.so','encbytea_in' 65 | LANGUAGE C STABLE STRICT; 66 | 67 | /* define output function of encrypted binary type */ 68 | CREATE FUNCTION 69 | encbytea_out(encrypt_bytea) 70 | RETURNS 71 | cstring 72 | AS 73 | '/usr/lib64/data_encryption.so','encbytea_out' 74 | LANGUAGE C STABLE STRICT; 75 | 76 | /* define recv function of encrypted binary type */ 77 | CREATE FUNCTION 78 | encbytea_recv(internal) 79 | RETURNS 80 | encrypt_bytea 81 | AS 82 | '/usr/lib64/data_encryption.so','encrecv' 83 | LANGUAGE C IMMUTABLE STRICT; 84 | 85 | /* define send function of encrypted binary type */ 86 | CREATE FUNCTION 87 | encbytea_send(encrypt_bytea) 88 | RETURNS 89 | bytea 90 | AS 91 | '/usr/lib64/data_encryption.so','encsend' 92 | LANGUAGE C IMMUTABLE STRICT; 93 | 94 | /* define encrypted text types */ 95 | CREATE TYPE ENCRYPT_TEXT ( 96 | INPUT = enctext_in 97 | , OUTPUT = enctext_out 98 | , RECEIVE = enctext_recv 99 | , SEND = enctext_send 100 | , INTERNALLENGTH = VARIABLE 101 | , ALIGNMENT = int4 102 | , STORAGE = extended 103 | , CATEGORY = 'S'); 104 | 105 | /* define encrypted binary types */ 106 | CREATE TYPE ENCRYPT_BYTEA ( 107 | INPUT = encbytea_in 108 | , OUTPUT = encbytea_out 109 | , RECEIVE = encbytea_recv 110 | , SEND = encbytea_send 111 | , INTERNALLENGTH = VARIABLE 112 | , ALIGNMENT = int4 113 | , STORAGE = extended 114 | , CATEGORY = 'U'); 115 | 116 | /* index operator of encrypted text types */ 117 | CREATE OR REPLACE FUNCTION 118 | enc_compeq_enctext(encrypt_text,encrypt_text) 119 | RETURNS 120 | bool 121 | AS 122 | '/usr/lib64/data_encryption.so','enc_compeq_enctext' 123 | LANGUAGE C STABLE STRICT; 124 | 125 | /* index operator of encrypted binary types */ 126 | CREATE OR REPLACE FUNCTION 127 | enc_compeq_encbytea(encrypt_bytea,encrypt_bytea) 128 | RETURNS 129 | bool 130 | AS 131 | '/usr/lib64/data_encryption.so','enc_compeq_encbytea' 132 | LANGUAGE C STABLE STRICT; 133 | 134 | /* hash function for encrypted text */ 135 | CREATE OR REPLACE FUNCTION 136 | enc_hash_enctext(encrypt_text) 137 | RETURNS 138 | integer 139 | AS 140 | '/usr/lib64/data_encryption.so','enc_hash_encdata' 141 | LANGUAGE C STRICT IMMUTABLE; 142 | 143 | /* hash function for encrypted binary */ 144 | CREATE OR REPLACE FUNCTION 145 | enc_hash_encbytea(encrypt_bytea) 146 | RETURNS 147 | integer 148 | AS 149 | '/usr/lib64/data_encryption.so','enc_hash_encdata' 150 | LANGUAGE C STRICT IMMUTABLE; 151 | 152 | /* load current encryption key */ 153 | CREATE OR REPLACE FUNCTION 154 | enc_store_key_info(text, text) 155 | RETURNS 156 | bool 157 | AS 158 | '/usr/lib64/data_encryption.so','enc_store_key_info' 159 | LANGUAGE C STRICT; 160 | 161 | /* load old key to memory for re-encryption */ 162 | CREATE OR REPLACE FUNCTION 163 | enc_store_old_key_info(text, text) 164 | RETURNS 165 | bool 166 | AS 167 | '/usr/lib64/data_encryption.so','enc_store_old_key_info' 168 | LANGUAGE C STRICT; 169 | 170 | /* drops key information from memory */ 171 | CREATE OR REPLACE FUNCTION 172 | enc_drop_key_info() 173 | RETURNS 174 | bool 175 | AS 176 | '/usr/lib64/data_encryption.so','enc_drop_key_info' 177 | LANGUAGE C STRICT; 178 | 179 | /* drops old key information from memory */ 180 | CREATE OR REPLACE FUNCTION 181 | enc_drop_old_key_info() 182 | RETURNS 183 | bool 184 | AS 185 | '/usr/lib64/data_encryption.so','enc_drop_old_key_info' 186 | LANGUAGE C STRICT; 187 | 188 | /* rename bakcup file, if it is exists */ 189 | CREATE OR REPLACE FUNCTION 190 | enc_rename_backupfile(text,text) 191 | RETURNS 192 | bool 193 | AS 194 | '/usr/lib64/data_encryption.so','enc_rename_backupfile' 195 | LANGUAGE C STRICT; 196 | 197 | CREATE OR REPLACE FUNCTION 198 | mask_activity() 199 | RETURNS 200 | void 201 | AS 202 | '/usr/lib64/data_encryption.so','mask_activity' 203 | LANGUAGE C STABLE STRICT; 204 | 205 | /* define index operator */ 206 | /* for encrypted text */ 207 | CREATE OPERATOR = ( 208 | leftarg = encrypt_text, rightarg = encrypt_text, procedure = enc_compeq_enctext, restrict = eqsel, join = eqjoinsel, hashes, commutator = operator(=)); 209 | /* for encrypted binary */ 210 | CREATE OPERATOR = ( 211 | leftarg = encrypt_bytea, rightarg = encrypt_bytea, procedure = enc_compeq_encbytea, restrict = eqsel, join = eqjoinsel, hashes, commutator = operator(=)); 212 | 213 | /* define index for encrypted type column */ 214 | /* define hash index for encrypted text */ 215 | CREATE OPERATOR CLASS 216 | hashtext_enc_ops 217 | DEFAULT FOR TYPE 218 | encrypt_text 219 | USING 220 | hash 221 | AS 222 | OPERATOR 1 = (encrypt_text,encrypt_text), 223 | FUNCTION 1 enc_hash_enctext(encrypt_text); 224 | 225 | /* define hash index for encrypted binary */ 226 | CREATE OPERATOR CLASS 227 | hashbytea_enc_ops 228 | DEFAULT FOR TYPE 229 | encrypt_bytea 230 | USING 231 | hash 232 | AS 233 | OPERATOR 1 = (encrypt_bytea,encrypt_bytea), 234 | FUNCTION 1 enc_hash_encbytea(encrypt_bytea); 235 | 236 | /* define cast function for encrypted type column */ 237 | CREATE OR REPLACE FUNCTION 238 | enctext(boolean) 239 | RETURNS 240 | encrypt_text 241 | AS 242 | '/usr/lib64/data_encryption.so','boolenctext' 243 | LANGUAGE C STRICT; 244 | 245 | CREATE OR REPLACE FUNCTION 246 | enctext(character) 247 | RETURNS 248 | encrypt_text 249 | AS 250 | '/usr/lib64/data_encryption.so','enctextrtrim' 251 | LANGUAGE C STABLE STRICT; 252 | 253 | CREATE OR REPLACE FUNCTION 254 | enctext(inet) 255 | RETURNS 256 | encrypt_text 257 | AS 258 | '/usr/lib64/data_encryption.so','inetenctext' 259 | LANGUAGE C STABLE STRICT; 260 | 261 | CREATE OR REPLACE FUNCTION 262 | enctext(xml) 263 | RETURNS 264 | encrypt_text 265 | AS 266 | '/usr/lib64/data_encryption.so','xmlenctext' 267 | LANGUAGE C STABLE STRICT; 268 | 269 | CREATE OR REPLACE FUNCTION 270 | regclass(encrypt_text) 271 | RETURNS 272 | regclass 273 | AS 274 | '/usr/lib64/data_encryption.so','enctext_regclass' 275 | LANGUAGE C STABLE STRICT; 276 | 277 | /* encrypted test -> text */ 278 | CREATE CAST 279 | (encrypt_text AS text) 280 | WITH INOUT 281 | AS IMPLICIT; 282 | /* text -> encrypted text */ 283 | CREATE CAST 284 | (text AS encrypt_text) 285 | WITH INOUT 286 | AS ASSIGNMENT; 287 | /* boolean -> encrypted text */ 288 | CREATE CAST 289 | (boolean AS encrypt_text) 290 | WITH FUNCTION enctext(boolean) 291 | AS ASSIGNMENT; 292 | /* character -> encrypted text */ 293 | CREATE CAST 294 | (character AS encrypt_text) 295 | WITH FUNCTION enctext(character) 296 | AS ASSIGNMENT; 297 | /* cidr -> encrypted text */ 298 | CREATE CAST 299 | (cidr AS encrypt_text) 300 | WITH FUNCTION enctext(inet) 301 | AS ASSIGNMENT; 302 | /* inet -> encrypted text */ 303 | CREATE CAST 304 | (inet AS encrypt_text) 305 | WITH FUNCTION enctext(inet) 306 | AS ASSIGNMENT; 307 | /* xml -> encrypted text */ 308 | CREATE CAST 309 | (xml AS encrypt_text) 310 | WITH FUNCTION enctext(xml) 311 | AS ASSIGNMENT; 312 | /* encrypted text -> regclass */ 313 | CREATE CAST 314 | (encrypt_text AS regclass) 315 | WITH FUNCTION regclass(encrypt_text) 316 | AS ASSIGNMENT; 317 | 318 | /* binary -> encrypted binary */ 319 | CREATE CAST 320 | (encrypt_bytea AS bytea) 321 | WITH INOUT 322 | AS IMPLICIT; 323 | /* encrypted binary -> binary */ 324 | CREATE CAST 325 | (bytea AS encrypt_bytea) 326 | WITH INOUT 327 | AS ASSIGNMENT; 328 | 329 | /* define table for managing encryption key */ 330 | DROP TABLE IF EXISTS cipher_key_table; 331 | CREATE TABLE cipher_key_table (key BYTEA 332 | , algorithm TEXT); 333 | -------------------------------------------------------------------------------- /SOURCES/lib/init/cipher_key_function.sql: -------------------------------------------------------------------------------- 1 | SET search_path TO public; 2 | SET check_function_bodies TO off; 3 | 4 | /*------------------------------------------------------------* 5 | * Function : cipher_key_regist 6 | * 7 | * add new key to the encryption key table 8 | * 9 | * @param TEXT $1 current encryption key 10 | * @param TEXT $2 new encryption key 11 | * @param TEXT $3 encryption algorithm 12 | *------------------------------------------------------------*/ 13 | CREATE OR REPLACE FUNCTION cipher_key_regist (TEXT, TEXT, TEXT) RETURNS INTEGER AS $$ 14 | 15 | DECLARE 16 | current_cipher_key ALIAS FOR $1; 17 | cipher_key ALIAS FOR $2; 18 | cipher_algorithm ALIAS FOR $3; 19 | 20 | current_cipher_algorithm TEXT; 21 | 22 | f_key_num SMALLINT; /* number of encryption key*/ 23 | 24 | BEGIN 25 | /* mask pg_stat_activity's query */ 26 | PERFORM mask_activity(); 27 | 28 | /* if cipher_key_disable_log is not yet executed, output an error */ 29 | IF (SELECT setting FROM pg_settings WHERE name = 'encrypt.mask_cipherkeylog') != 'on' THEN 30 | RAISE EXCEPTION 'TDE-E0036 you must call cipher_key_disable_log function first[02].'; 31 | END IF; 32 | 33 | IF cipher_key IS NULL OR cipher_key = '' THEN 34 | RAISE EXCEPTION 'TDE-E0002 new cipher key is invalid[01]'; 35 | END IF; 36 | 37 | /* validate encryption algorithm */ 38 | IF cipher_algorithm != 'aes' AND cipher_algorithm != 'bf' THEN 39 | RAISE EXCEPTION 'TDE-E0003 invalid cipher algorithm "%"[01]', cipher_algorithm; 40 | END IF; 41 | 42 | SET LOCAL search_path TO public; 43 | SET LOCAL enable_seqscan TO off; 44 | 45 | /* obtain lock of enryption key table */ 46 | LOCK TABLE cipher_key_table IN EXCLUSIVE MODE; 47 | 48 | /* getting the number of encryption key */ 49 | SELECT count(*) INTO f_key_num FROM cipher_key_table; 50 | /* if encryption key is already exist */ 51 | IF f_key_num = 1 THEN 52 | IF current_cipher_key IS NULL THEN 53 | RAISE EXCEPTION 'TDE-E0008 current cipher key is not correct[01]'; 54 | END IF; 55 | /* if current key is valid and save current encryption algorithm*/ 56 | BEGIN 57 | SELECT algorithm INTO current_cipher_algorithm FROM cipher_key_table WHERE pgp_sym_decrypt(key, current_cipher_key)=current_cipher_key; 58 | EXCEPTION 59 | WHEN SQLSTATE '39000' THEN 60 | RAISE EXCEPTION 'TDE-E0008 current cipher key is not correct[01]'; 61 | END; 62 | /* delete current key */ 63 | DELETE FROM cipher_key_table; 64 | 65 | /* too many key is exists */ 66 | ELSEIF f_key_num > 1 THEN 67 | RAISE EXCEPTION 'TDE-E0009 too many encryption keys are exists in cipher_key_table[01]'; 68 | END IF; 69 | 70 | /* encrypt and register new key */ 71 | INSERT INTO cipher_key_table(key, algorithm) VALUES(pgp_sym_encrypt(cipher_key, cipher_key, 'cipher-algo=aes256, s2k-mode=1'), cipher_algorithm); 72 | 73 | /* backup encryption key table */ 74 | PERFORM cipher_key_backup(); 75 | /* reencrypt all data */ 76 | IF f_key_num = 1 THEN 77 | PERFORM cipher_key_reencrypt_data(current_cipher_key, current_cipher_algorithm, cipher_key); 78 | END IF; 79 | 80 | /* return 1 */ 81 | RETURN 1; 82 | END; 83 | $$ LANGUAGE plpgsql; 84 | 85 | 86 | /*------------------------------------------------------------* 87 | * Function : cipher_key_reencrypt_data 88 | * 89 | * re-encrypt specified data periodically using encryption key 90 | * which is specified custom parameter 91 | * 92 | * @return true if re-encryption is successfully done 93 | *------------------------------------------------------------*/ 94 | CREATE OR REPLACE FUNCTION cipher_key_reencrypt_data (TEXT, TEXT, TEXT) RETURNS BOOLEAN AS $$ 95 | 96 | DECLARE 97 | 98 | old_cipher_key ALIAS FOR $1; 99 | old_cipher_algorithm ALIAS FOR $2; 100 | new_cipher_key ALIAS FOR $3; 101 | 102 | f_rec RECORD; /* store target update column */ 103 | f_rec2 RECORD; /* store target update row */ 104 | f_cu REFCURSOR; /* fetch target update column */ 105 | f_cu2 REFCURSOR; /* fetch target update row */ 106 | 107 | f_counter BIGINT; /* number of processed target record*/ 108 | f_result BIGINT; 109 | 110 | f_query TEXT; /* store dynamic SQL string */ 111 | 112 | f_relid BIGINT; 113 | f_nspname TEXT; 114 | f_relname TEXT; 115 | f_islast BOOLEAN; 116 | 117 | BEGIN 118 | /* init */ 119 | f_counter := 0; 120 | f_relid := 0; 121 | f_nspname = ''; 122 | f_relname = ''; 123 | f_islast = FALSE; 124 | 125 | SET LOCAL search_path TO public; 126 | SET LOCAL encrypt.enable TO on; 127 | SET LOCAL encrypt.noversionerror TO on; 128 | 129 | /* set new key to memory */ 130 | PERFORM pgtde_begin_session(new_cipher_key); 131 | /* set old key to memory */ 132 | PERFORM enc_store_old_key_info(old_cipher_key, old_cipher_algorithm); 133 | 134 | /* store column of user defined table */ 135 | OPEN 136 | f_cu 137 | FOR 138 | SELECT a.attrelid, n.nspname, c.relname, a.attname, t.typname 139 | FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n 140 | WHERE a.attrelid = c.oid 141 | AND t.oid = a.atttypid 142 | AND c.relnamespace = n.oid 143 | AND c.relkind = 'r' 144 | AND t.typname IN ('encrypt_text', 'encrypt_bytea') 145 | AND n.nspname != 'information_schema' 146 | AND n.nspname NOT LIKE E'pg\\_%' 147 | ORDER BY nspname, relname, attname; 148 | 149 | 150 | /* re-encryption */ 151 | FETCH f_cu INTO f_rec; 152 | IF NOT FOUND THEN 153 | f_islast := TRUE; 154 | END IF; 155 | 156 | /* update each encrypted column */ 157 | LOOP 158 | IF f_islast THEN 159 | EXIT; 160 | END IF; 161 | 162 | f_relid := f_rec.attrelid; 163 | f_nspname := f_rec.nspname; 164 | f_relname := f_rec.relname; 165 | 166 | f_query := 'UPDATE ONLY ' || quote_ident(f_rec.nspname) || '.' || quote_ident(f_rec.relname) || ' SET '; 167 | 168 | LOOP 169 | IF f_rec.typname = 'encrypt_text' THEN 170 | f_query := f_query || quote_ident(f_rec.attname) || ' = ' || quote_ident(f_rec.attname) || '::text::encrypt_text '; 171 | ELSE 172 | f_query := f_query || quote_ident(f_rec.attname) || ' = ' || quote_ident(f_rec.attname) || '::bytea::encrypt_bytea '; 173 | END IF; 174 | 175 | FETCH f_cu INTO f_rec; 176 | IF NOT FOUND THEN 177 | f_islast := TRUE; 178 | END IF; 179 | 180 | IF f_islast OR f_relid != f_rec.attrelid THEN 181 | f_query := f_query || ';'; 182 | EXIT; 183 | ELSE 184 | f_query := f_query || ', '; 185 | END IF; 186 | END LOOP; 187 | 188 | RAISE INFO 'TDE-I0001 re-encryption of table "%"."%" was started[01]', f_nspname, f_relname; 189 | 190 | EXECUTE f_query; 191 | 192 | RAISE INFO 'TDE-I0002 re-encryption of table "%"."%" was completed[01]', f_nspname, f_relname; 193 | END LOOP; 194 | 195 | CLOSE f_cu; 196 | 197 | /* delete old key from memory */ 198 | PERFORM enc_drop_old_key_info(); 199 | /* drop key from memory */ 200 | PERFORM pgtde_end_session(); 201 | 202 | RETURN TRUE; 203 | END; 204 | $$ LANGUAGE plpgsql; 205 | 206 | 207 | /*------------------------------------------------------------* 208 | * Function : cipher_key_backup 209 | * 210 | * backup encryption key table 211 | * if backup already exists, rename backup to .sv 212 | * and backup current key table 213 | * 214 | * @return true, if 215 | *------------------------------------------------------------*/ 216 | CREATE OR REPLACE FUNCTION cipher_key_backup () RETURNS BOOLEAN AS $$ 217 | 218 | DECLARE 219 | f_filepath TEXT; /* path of backupfile */ 220 | f_old_filepath TEXT; /* old backupfile */ 221 | f_query TEXT; /* dynamic SQL */ 222 | f_dbname TEXT; /* current dbname */ 223 | result BOOLEAN; 224 | 225 | BEGIN 226 | /* get path of backup file from encrypt.backup */ 227 | SELECT setting INTO f_filepath FROM pg_settings WHERE name = 'encrypt.backup'; 228 | 229 | /* if encrypt.backup is not set, get value of data_directory */ 230 | IF(f_filepath = '')THEN 231 | SELECT setting INTO f_filepath FROM pg_settings WHERE name = 'data_directory'; 232 | 233 | IF f_filepath IS NULL THEN 234 | RAISE EXCEPTION 'TDE-E0014 could not get data directory path[01]'; 235 | END IF; 236 | END IF; 237 | 238 | /* get name of current db */ 239 | SELECT current_database() INTO f_dbname; 240 | 241 | /* set filename of backup */ 242 | f_filepath := f_filepath || E'/ck_backup_' || f_dbname; 243 | f_old_filepath := f_filepath || E'.sv'; 244 | 245 | /* rename if "ck_backup" is already exists */ 246 | SELECT enc_rename_backupfile(f_filepath, f_old_filepath) INTO result; 247 | 248 | IF result = FALSE THEN 249 | RAISE EXCEPTION 'TDE-E0015 could not rename old backup file of cipher key[01]'; 250 | END IF; 251 | 252 | /* backup current encryption key table */ 253 | f_query := 'COPY cipher_key_table TO ''' || f_filepath || ''''; 254 | EXECUTE f_query; 255 | 256 | RETURN result; 257 | END; 258 | $$ LANGUAGE plpgsql 259 | SET search_path TO public; 260 | 261 | 262 | /*------------------------------------------------------------* 263 | * Function : cipher_key_disable_log 264 | * 265 | * set track_activities to off and encrypt.mask_cipherkeylog to on. 266 | * In order to remove cipher info in pg_stat_activity's query. 267 | * 268 | * @return TRUE 269 | *------------------------------------------------------------*/ 270 | CREATE OR REPLACE FUNCTION cipher_key_disable_log () RETURNS BOOLEAN AS $$ 271 | 272 | DECLARE 273 | save_result BOOLEAN; /* result of backup current parameter */ 274 | 275 | BEGIN 276 | 277 | SET track_activities = off; 278 | SET encrypt.mask_cipherkeylog = on; 279 | RETURN TRUE; 280 | 281 | END; 282 | $$ LANGUAGE plpgsql 283 | SECURITY DEFINER 284 | SET search_path TO public; 285 | 286 | 287 | /*------------------------------------------------------------* 288 | * Function : cipher_key_enable_log 289 | * 290 | * set back track_activities to default and encrypt.mask_cipherkeylog to off. 291 | * 292 | * @return TRUE 293 | *------------------------------------------------------------*/ 294 | CREATE OR REPLACE FUNCTION cipher_key_enable_log () RETURNS BOOLEAN AS $$ 295 | 296 | DECLARE 297 | save_result BOOLEAN; 298 | 299 | BEGIN 300 | 301 | SET track_activities = DEFAULT; 302 | SET encrypt.mask_cipherkeylog = off; 303 | RETURN TRUE; 304 | 305 | END; 306 | $$ LANGUAGE plpgsql 307 | SECURITY DEFINER 308 | SET search_path TO public; 309 | 310 | /*------------------------------------------------------------* 311 | * Function : pgtde_version() 312 | * 313 | * return current TDE version. 314 | * 315 | *------------------------------------------------------------*/ 316 | CREATE OR REPLACE FUNCTION pgtde_version() RETURNS TEXT AS $$ 317 | BEGIN 318 | RETURN 'Free Edition 1.2.1.0'; 319 | END; 320 | $$ LANGUAGE plpgsql; 321 | 322 | -------------------------------------------------------------------------------- /SOURCES/lib/init/common_session_create.sql: -------------------------------------------------------------------------------- 1 | SET search_path TO public; 2 | SET check_function_bodies TO off; 3 | 4 | /*------------------------------------------------------------* 5 | * Function : pgtde_begin_session 6 | * 7 | * load encryption key table to memory 8 | * exception will be raised in below cases 9 | * 1. value of log_statement is 'all' 10 | * 2. encryption key is invalid 11 | * 12 | * @param TEXT $1 lastest encryption key 13 | * @return result of load encryption key table to memory 14 | *------------------------------------------------------------*/ 15 | CREATE OR REPLACE FUNCTION pgtde_begin_session (TEXT) RETURNS BOOLEAN AS $$ 16 | 17 | DECLARE 18 | cipher_key ALIAS FOR $1; 19 | 20 | f_algorithm TEXT; /* encryption algorithm of lastest key */ 21 | f_key_num INTEGER; /* number of encryption key */ 22 | f_result BOOLEAN; 23 | 24 | BEGIN 25 | /* mask pg_stat_activity's query */ 26 | PERFORM mask_activity(); 27 | 28 | /* if cipher_key_disable_log is not yet executed, output an error */ 29 | IF (SELECT setting FROM pg_settings WHERE name = 'encrypt.mask_cipherkeylog') != 'on' THEN 30 | RAISE EXCEPTION 'TDE-E0036 you must call cipher_key_disable_log function first[01].'; 31 | END IF; 32 | 33 | /* drop encryption key information in memory */ 34 | PERFORM enc_drop_key_info(); 35 | /* drop old-encryption key information in memory */ 36 | PERFORM enc_drop_old_key_info(); 37 | 38 | IF cipher_key IS NOT NULL THEN 39 | /* get number of registered encryption key */ 40 | SELECT count(*) INTO f_key_num FROM cipher_key_table; 41 | 42 | /* return false, if there is no or too many encryption key */ 43 | IF f_key_num = 0 THEN 44 | RETURN FALSE; 45 | ELSIF f_key_num>1 THEN 46 | RAISE EXCEPTION 'TDE-E0009 too many encryption keys are exists in cipher_key_table[02]'; 47 | END IF; 48 | 49 | BEGIN 50 | /* load encryption key table to memory */ 51 | PERFORM enc_store_key_info(pgp_sym_decrypt(key, cipher_key), algorithm) 52 | FROM (SELECT key, algorithm FROM cipher_key_table) AS ckt; 53 | EXCEPTION 54 | WHEN SQLSTATE '39000' THEN 55 | PERFORM enc_drop_key_info(); 56 | RAISE EXCEPTION 'TDE-E0012 cipher key is not correct[01]'; 57 | END; 58 | END IF; 59 | RETURN TRUE; 60 | END; 61 | $$ LANGUAGE plpgsql 62 | SET search_path TO public; 63 | 64 | 65 | /*------------------------------------------------------------* 66 | * Function : pgtde_end_session 67 | * 68 | * drop encryption key table from memory 69 | * return false, if there is no encryption key table in memory 70 | * 71 | * @return result of drop encryption key table in memory 72 | *------------------------------------------------------------*/ 73 | CREATE OR REPLACE FUNCTION pgtde_end_session () RETURNS BOOLEAN AS $$ 74 | 75 | BEGIN 76 | /* drop encryption key table in memory */ 77 | IF (SELECT enc_drop_key_info()) THEN 78 | RETURN TRUE; 79 | ELSE 80 | RETURN FALSE; 81 | END IF; 82 | END; 83 | $$ LANGUAGE plpgsql 84 | SET search_path TO public; 85 | -------------------------------------------------------------------------------- /SOURCES/lib/init/common_session_dummy_create.sql: -------------------------------------------------------------------------------- 1 | SET search_path TO public; 2 | SET check_function_bodies TO off; 3 | 4 | 5 | /*------------------------------------------------------------* 6 | * Function : pgtde_begin_session 7 | * 8 | * @param TEXT $1 do not used 9 | * @return result of load encryption key table to memory 10 | *------------------------------------------------------------*/ 11 | CREATE OR REPLACE FUNCTION pgtde_begin_session (TEXT) RETURNS BOOLEAN AS $$ 12 | 13 | BEGIN 14 | RETURN TRUE; 15 | END; 16 | $$ LANGUAGE plpgsql; 17 | 18 | 19 | /*------------------------------------------------------------* 20 | * Function : pgtde_end_session 21 | * 22 | * restore search path 23 | * 24 | * @return true when encryption is not used 25 | *------------------------------------------------------------*/ 26 | CREATE OR REPLACE FUNCTION pgtde_end_session () RETURNS BOOLEAN AS $$ 27 | 28 | BEGIN 29 | RETURN TRUE; 30 | END; 31 | $$ LANGUAGE plpgsql; 32 | -------------------------------------------------------------------------------- /SOURCES/lib/init/pgtde_parallel_safe_setting.sql: -------------------------------------------------------------------------------- 1 | 2 | --- add parallel unsafe for PostgreSQL greater than 9.6 --- 3 | --- TDEforPG does not support Parallel Query Feature. --- 4 | 5 | -------------------------------------------------------------------------------------- 6 | ---------------------------------- pgcrypto sql function ----------------------------- 7 | -------------------------------------------------------------------------------------- 8 | 9 | -------------------------------------------------------------------------------------- 10 | -------------------------------------- parallel unsafe function ---------------------- 11 | -------------------------------------------------------------------------------------- 12 | ALTER FUNCTION decrypt ( bytea, bytea, text ) PARALLEL UNSAFE; 13 | ALTER FUNCTION encrypt ( bytea, bytea, text ) PARALLEL UNSAFE; 14 | ALTER FUNCTION pgp_sym_decrypt ( bytea, text ) PARALLEL UNSAFE; 15 | ALTER FUNCTION pgp_sym_decrypt ( bytea, text, text ) PARALLEL UNSAFE; 16 | ALTER FUNCTION pgp_sym_encrypt ( text, text ) PARALLEL UNSAFE; 17 | ALTER FUNCTION pgp_sym_encrypt ( text, text, text ) PARALLEL UNSAFE; 18 | -------------------------------------------------------------------------------------- 19 | 20 | -------------------------------------------------------------------------------------- 21 | ---------------------------------- TDEforPG defined function ------------------------- 22 | -------------------------------------------------------------------------------------- 23 | -- Default of create function is parallel unsafe. All of TDEforPG's functions are 24 | -- PARALLEL UNSAFE. So it is necessary to ALTER them here. 25 | 26 | 27 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_0_0_0.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(encrypt_bytea) 6 | FUNCTION public encbytea_out(public.encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(encrypt_bytea) 9 | FUNCTION public encbytea_send(public.encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(encrypt_text) 14 | FUNCTION public enctext_out(public.encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(encrypt_text) 17 | FUNCTION public enctext_send(public.encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_bytea_encbytea(bytea, encrypt_bytea) 25 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 26 | FUNCTION public enc_compeq_encbytea_bytea(encrypt_bytea, bytea) 27 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 28 | FUNCTION public enc_compeq_enctext_text(encrypt_text, text) 29 | FUNCTION public enc_compeq_text_enctext(text, encrypt_text) 30 | FUNCTION public enc_compeq_bytea_encbytea(bytea, public.encrypt_bytea) 31 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 32 | FUNCTION public enc_compeq_encbytea_bytea(public.encrypt_bytea, bytea) 33 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 34 | FUNCTION public enc_compeq_enctext_text(public.encrypt_text, text) 35 | FUNCTION public enc_compeq_text_enctext(text, public.encrypt_text) 36 | FUNCTION public enc_drop_key_info() 37 | FUNCTION public enc_drop_old_key_info() 38 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 39 | FUNCTION public enc_hash_enctext(encrypt_text) 40 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 41 | FUNCTION public enc_hash_enctext(public.encrypt_text) 42 | FUNCTION public enc_rename_backupfile(text, text) 43 | FUNCTION public enc_restore_logsetting() 44 | FUNCTION public enc_save_logsetting() 45 | FUNCTION public enc_store_key_info(text, text) 46 | FUNCTION public enc_store_old_key_info(text, text) 47 | FUNCTION public pgtde_begin_session(text) 48 | FUNCTION public pgtde_end_session() 49 | OPERATOR FAMILY public hashbytea_enc_ops 50 | OPERATOR CLASS public hashbytea_enc_ops 51 | OPERATOR FAMILY public hashtext_enc_ops 52 | OPERATOR CLASS public hashtext_enc_ops 53 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 54 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 55 | CAST pg_catalog CAST (public.encrypt_text AS text) 56 | CAST pg_catalog CAST (text AS public.encrypt_text) 57 | CAST (bytea AS public.encrypt_bytea) 58 | CAST (public.encrypt_bytea AS bytea) 59 | CAST (public.encrypt_text AS text) 60 | CAST (text AS public.encrypt_text) 61 | TABLE public cipher_key_table 62 | ACL public cipher_key_table 63 | TABLE cipher_key_table 64 | TABLE DATA public cipher_key_table 65 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_1_0_0.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(encrypt_bytea) 6 | FUNCTION public encbytea_out(public.encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(encrypt_bytea) 9 | FUNCTION public encbytea_send(public.encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(encrypt_text) 14 | FUNCTION public enctext_out(public.encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(encrypt_text) 17 | FUNCTION public enctext_send(public.encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 25 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 26 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 27 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 28 | FUNCTION public enc_drop_key_info() 29 | FUNCTION public enc_drop_old_key_info() 30 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 31 | FUNCTION public enc_hash_enctext(encrypt_text) 32 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 33 | FUNCTION public enc_hash_enctext(public.encrypt_text) 34 | FUNCTION public enc_rename_backupfile(text, text) 35 | FUNCTION public enc_restore_logsetting() 36 | FUNCTION public enc_save_logsetting() 37 | FUNCTION public enc_store_key_info(text, text) 38 | FUNCTION public enc_store_old_key_info(text, text) 39 | FUNCTION public enctext(boolean) 40 | FUNCTION public enctext(character) 41 | FUNCTION public enctext(inet) 42 | FUNCTION public enctext(xml) 43 | FUNCTION public pgtde_begin_session(text) 44 | FUNCTION public pgtde_end_session() 45 | FUNCTION public regclass(encrypt_text) 46 | FUNCTION public regclass(public.encrypt_text) 47 | OPERATOR FAMILY public hashbytea_enc_ops 48 | OPERATOR CLASS public hashbytea_enc_ops 49 | OPERATOR FAMILY public hashtext_enc_ops 50 | OPERATOR CLASS public hashtext_enc_ops 51 | CAST pg_catalog CAST (boolean AS public.encrypt_text) 52 | CAST pg_catalog CAST (character AS public.encrypt_text) 53 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 54 | CAST pg_catalog CAST (cidr AS public.encrypt_text) 55 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 56 | CAST pg_catalog CAST (public.encrypt_text AS regclass) 57 | CAST pg_catalog CAST (public.encrypt_text AS text) 58 | CAST pg_catalog CAST (inet AS public.encrypt_text) 59 | CAST pg_catalog CAST (text AS public.encrypt_text) 60 | CAST pg_catalog CAST (xml AS public.encrypt_text) 61 | CAST (boolean AS public.encrypt_text) 62 | CAST (character AS public.encrypt_text) 63 | CAST (bytea AS public.encrypt_bytea) 64 | CAST (cidr AS public.encrypt_text) 65 | CAST (public.encrypt_bytea AS bytea) 66 | CAST (public.encrypt_text AS regclass) 67 | CAST (public.encrypt_text AS text) 68 | CAST (inet AS public.encrypt_text) 69 | CAST (text AS public.encrypt_text) 70 | CAST (xml AS public.encrypt_text) 71 | TABLE public cipher_key_table 72 | ACL public cipher_key_table 73 | ACL public TABLE cipher_key_table 74 | TABLE DATA public cipher_key_table 75 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_1_1_0.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(encrypt_bytea) 6 | FUNCTION public encbytea_out(public.encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(encrypt_bytea) 9 | FUNCTION public encbytea_send(public.encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(encrypt_text) 14 | FUNCTION public enctext_out(public.encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(encrypt_text) 17 | FUNCTION public enctext_send(public.encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 25 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 26 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 27 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 28 | FUNCTION public enc_drop_key_info() 29 | FUNCTION public enc_drop_old_key_info() 30 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 31 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 32 | FUNCTION public enc_hash_enctext(encrypt_text) 33 | FUNCTION public enc_hash_enctext(public.encrypt_text) 34 | FUNCTION public enc_rename_backupfile(text, text) 35 | FUNCTION public enc_store_key_info(text, text) 36 | FUNCTION public enc_store_old_key_info(text, text) 37 | FUNCTION public enctext(boolean) 38 | FUNCTION public enctext(character) 39 | FUNCTION public enctext(inet) 40 | FUNCTION public enctext(xml) 41 | FUNCTION public mask_activity() 42 | FUNCTION public pgtde_begin_session(text) 43 | FUNCTION public pgtde_end_session() 44 | FUNCTION public pgtde_version() 45 | FUNCTION public regclass(encrypt_text) 46 | FUNCTION public regclass(public.encrypt_text) 47 | OPERATOR FAMILY public hashbytea_enc_ops 48 | OPERATOR CLASS public hashbytea_enc_ops 49 | OPERATOR FAMILY public hashtext_enc_ops 50 | OPERATOR CLASS public hashtext_enc_ops 51 | CAST pg_catalog CAST (boolean AS public.encrypt_text) 52 | CAST pg_catalog CAST (character AS public.encrypt_text) 53 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 54 | CAST pg_catalog CAST (cidr AS public.encrypt_text) 55 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 56 | CAST pg_catalog CAST (public.encrypt_text AS regclass) 57 | CAST pg_catalog CAST (public.encrypt_text AS text) 58 | CAST pg_catalog CAST (inet AS public.encrypt_text) 59 | CAST pg_catalog CAST (text AS public.encrypt_text) 60 | CAST pg_catalog CAST (xml AS public.encrypt_text) 61 | CAST (boolean AS public.encrypt_text) 62 | CAST (character AS public.encrypt_text) 63 | CAST (bytea AS public.encrypt_bytea) 64 | CAST (cidr AS public.encrypt_text) 65 | CAST (public.encrypt_bytea AS bytea) 66 | CAST (public.encrypt_text AS regclass) 67 | CAST (public.encrypt_text AS text) 68 | CAST (inet AS public.encrypt_text) 69 | CAST (text AS public.encrypt_text) 70 | CAST (xml AS public.encrypt_text) 71 | TABLE public cipher_key_table 72 | ACL public cipher_key_table 73 | ACL public TABLE cipher_key_table 74 | TABLE DATA public cipher_key_table 75 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_1_1_1.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(encrypt_bytea) 6 | FUNCTION public encbytea_out(public.encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(encrypt_bytea) 9 | FUNCTION public encbytea_send(public.encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(encrypt_text) 14 | FUNCTION public enctext_out(public.encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(encrypt_text) 17 | FUNCTION public enctext_send(public.encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 25 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 26 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 27 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 28 | FUNCTION public enc_drop_key_info() 29 | FUNCTION public enc_drop_old_key_info() 30 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 31 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 32 | FUNCTION public enc_hash_enctext(encrypt_text) 33 | FUNCTION public enc_hash_enctext(public.encrypt_text) 34 | FUNCTION public enc_rename_backupfile(text, text) 35 | FUNCTION public enc_store_key_info(text, text) 36 | FUNCTION public enc_store_old_key_info(text, text) 37 | FUNCTION public enctext(boolean) 38 | FUNCTION public enctext(character) 39 | FUNCTION public enctext(inet) 40 | FUNCTION public enctext(xml) 41 | FUNCTION public mask_activity() 42 | FUNCTION public pgtde_begin_session(text) 43 | FUNCTION public pgtde_end_session() 44 | FUNCTION public pgtde_version() 45 | FUNCTION public regclass(encrypt_text) 46 | FUNCTION public regclass(public.encrypt_text) 47 | OPERATOR FAMILY public hashbytea_enc_ops 48 | OPERATOR CLASS public hashbytea_enc_ops 49 | OPERATOR FAMILY public hashtext_enc_ops 50 | OPERATOR CLASS public hashtext_enc_ops 51 | CAST pg_catalog CAST (boolean AS public.encrypt_text) 52 | CAST pg_catalog CAST (character AS public.encrypt_text) 53 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 54 | CAST pg_catalog CAST (cidr AS public.encrypt_text) 55 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 56 | CAST pg_catalog CAST (public.encrypt_text AS regclass) 57 | CAST pg_catalog CAST (public.encrypt_text AS text) 58 | CAST pg_catalog CAST (inet AS public.encrypt_text) 59 | CAST pg_catalog CAST (text AS public.encrypt_text) 60 | CAST pg_catalog CAST (xml AS public.encrypt_text) 61 | CAST (boolean AS public.encrypt_text) 62 | CAST (character AS public.encrypt_text) 63 | CAST (bytea AS public.encrypt_bytea) 64 | CAST (cidr AS public.encrypt_text) 65 | CAST (public.encrypt_bytea AS bytea) 66 | CAST (public.encrypt_text AS regclass) 67 | CAST (public.encrypt_text AS text) 68 | CAST (inet AS public.encrypt_text) 69 | CAST (text AS public.encrypt_text) 70 | CAST (xml AS public.encrypt_text) 71 | TABLE public cipher_key_table 72 | ACL public cipher_key_table 73 | ACL public TABLE cipher_key_table 74 | TABLE DATA public cipher_key_table 75 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_1_2_0.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(encrypt_bytea) 6 | FUNCTION public encbytea_out(public.encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(encrypt_bytea) 9 | FUNCTION public encbytea_send(public.encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(encrypt_text) 14 | FUNCTION public enctext_out(public.encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(encrypt_text) 17 | FUNCTION public enctext_send(public.encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 25 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 26 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 27 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 28 | FUNCTION public enc_drop_key_info() 29 | FUNCTION public enc_drop_old_key_info() 30 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 31 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 32 | FUNCTION public enc_hash_enctext(encrypt_text) 33 | FUNCTION public enc_hash_enctext(public.encrypt_text) 34 | FUNCTION public enc_rename_backupfile(text, text) 35 | FUNCTION public enc_store_key_info(text, text) 36 | FUNCTION public enc_store_old_key_info(text, text) 37 | FUNCTION public enctext(boolean) 38 | FUNCTION public enctext(character) 39 | FUNCTION public enctext(inet) 40 | FUNCTION public enctext(xml) 41 | FUNCTION public mask_activity() 42 | FUNCTION public pgtde_begin_session(text) 43 | FUNCTION public pgtde_end_session() 44 | FUNCTION public pgtde_version() 45 | FUNCTION public regclass(encrypt_text) 46 | FUNCTION public regclass(public.encrypt_text) 47 | OPERATOR FAMILY public hashbytea_enc_ops 48 | OPERATOR CLASS public hashbytea_enc_ops 49 | OPERATOR FAMILY public hashtext_enc_ops 50 | OPERATOR CLASS public hashtext_enc_ops 51 | CAST pg_catalog CAST (boolean AS public.encrypt_text) 52 | CAST pg_catalog CAST (character AS public.encrypt_text) 53 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 54 | CAST pg_catalog CAST (cidr AS public.encrypt_text) 55 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 56 | CAST pg_catalog CAST (public.encrypt_text AS regclass) 57 | CAST pg_catalog CAST (public.encrypt_text AS text) 58 | CAST pg_catalog CAST (inet AS public.encrypt_text) 59 | CAST pg_catalog CAST (text AS public.encrypt_text) 60 | CAST pg_catalog CAST (xml AS public.encrypt_text) 61 | CAST (boolean AS public.encrypt_text) 62 | CAST (character AS public.encrypt_text) 63 | CAST (bytea AS public.encrypt_bytea) 64 | CAST (cidr AS public.encrypt_text) 65 | CAST (public.encrypt_bytea AS bytea) 66 | CAST (public.encrypt_text AS regclass) 67 | CAST (public.encrypt_text AS text) 68 | CAST (inet AS public.encrypt_text) 69 | CAST (text AS public.encrypt_text) 70 | CAST (xml AS public.encrypt_text) 71 | TABLE public cipher_key_table 72 | ACL public cipher_key_table 73 | ACL public TABLE cipher_key_table 74 | TABLE DATA public cipher_key_table 75 | -------------------------------------------------------------------------------- /SOURCES/lib/upgrade/installed_list_fe_V1_2_1_0.txt: -------------------------------------------------------------------------------- 1 | EXTENSION - pgcrypto 2 | COMMENT - EXTENSION pgcrypto 3 | SHELL TYPE public encrypt_bytea 4 | FUNCTION public encbytea_in(cstring) 5 | FUNCTION public encbytea_out(public.encrypt_bytea) 6 | FUNCTION public encbytea_out(encrypt_bytea) 7 | FUNCTION public encbytea_recv(internal) 8 | FUNCTION public encbytea_send(public.encrypt_bytea) 9 | FUNCTION public encbytea_send(encrypt_bytea) 10 | TYPE public encrypt_bytea 11 | SHELL TYPE public encrypt_text 12 | FUNCTION public enctext_in(cstring) 13 | FUNCTION public enctext_out(public.encrypt_text) 14 | FUNCTION public enctext_out(encrypt_text) 15 | FUNCTION public enctext_recv(internal) 16 | FUNCTION public enctext_send(public.encrypt_text) 17 | FUNCTION public enctext_send(encrypt_text) 18 | TYPE public encrypt_text 19 | FUNCTION public cipher_key_backup() 20 | FUNCTION public cipher_key_disable_log() 21 | FUNCTION public cipher_key_enable_log() 22 | FUNCTION public cipher_key_reencrypt_data(text, text, text) 23 | FUNCTION public cipher_key_regist(text, text, text) 24 | FUNCTION public enc_compeq_encbytea(public.encrypt_bytea, public.encrypt_bytea) 25 | FUNCTION public enc_compeq_enctext(public.encrypt_text, public.encrypt_text) 26 | FUNCTION public enc_compeq_encbytea(encrypt_bytea, encrypt_bytea) 27 | FUNCTION public enc_compeq_enctext(encrypt_text, encrypt_text) 28 | FUNCTION public enc_drop_key_info() 29 | FUNCTION public enc_drop_old_key_info() 30 | FUNCTION public enc_hash_encbytea(public.encrypt_bytea) 31 | FUNCTION public enc_hash_enctext(public.encrypt_text) 32 | FUNCTION public enc_hash_encbytea(encrypt_bytea) 33 | FUNCTION public enc_hash_enctext(encrypt_text) 34 | FUNCTION public enc_rename_backupfile(text, text) 35 | FUNCTION public enc_store_key_info(text, text) 36 | FUNCTION public enc_store_old_key_info(text, text) 37 | FUNCTION public enctext(boolean) 38 | FUNCTION public enctext(character) 39 | FUNCTION public enctext(inet) 40 | FUNCTION public enctext(xml) 41 | FUNCTION public mask_activity() 42 | FUNCTION public pgtde_begin_session(text) 43 | FUNCTION public pgtde_end_session() 44 | FUNCTION public pgtde_version() 45 | FUNCTION public regclass(public.encrypt_text) 46 | OPERATOR FAMILY public hashbytea_enc_ops 47 | OPERATOR CLASS public hashbytea_enc_ops 48 | OPERATOR FAMILY public hashtext_enc_ops 49 | OPERATOR CLASS public hashtext_enc_ops 50 | CAST (boolean AS public.encrypt_text) 51 | CAST (character AS public.encrypt_text) 52 | CAST (bytea AS public.encrypt_bytea) 53 | CAST (cidr AS public.encrypt_text) 54 | CAST (public.encrypt_bytea AS bytea) 55 | CAST (public.encrypt_text AS regclass) 56 | CAST (public.encrypt_text AS text) 57 | CAST (inet AS public.encrypt_text) 58 | CAST (text AS public.encrypt_text) 59 | CAST (xml AS public.encrypt_text) 60 | FUNCTION public regclass(encrypt_text) 61 | CAST pg_catalog CAST (boolean AS public.encrypt_text) 62 | CAST pg_catalog CAST (character AS public.encrypt_text) 63 | CAST pg_catalog CAST (bytea AS public.encrypt_bytea) 64 | CAST pg_catalog CAST (cidr AS public.encrypt_text) 65 | CAST pg_catalog CAST (public.encrypt_bytea AS bytea) 66 | CAST pg_catalog CAST (public.encrypt_text AS regclass) 67 | CAST pg_catalog CAST (public.encrypt_text AS text) 68 | CAST pg_catalog CAST (inet AS public.encrypt_text) 69 | CAST pg_catalog CAST (text AS public.encrypt_text) 70 | CAST pg_catalog CAST (xml AS public.encrypt_text) 71 | TABLE public cipher_key_table 72 | ACL public TABLE cipher_key_table 73 | ACL public cipher_key_table 74 | TABLE DATA public cipher_key_table 75 | -------------------------------------------------------------------------------- /SOURCES/sys/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/SOURCES/sys/.gitkeep -------------------------------------------------------------------------------- /SOURCES/test/README: -------------------------------------------------------------------------------- 1 | Precaution 2 | ========== 3 | DO NOT RUN TESTS IN PRODUCTION SYSTEM OR OTHER SYSTEM WHERE RIST OF LOSS OF DATA IS NOT ACCEPTABLE. 4 | 5 | Requirements 6 | ============ 7 | 1. pgTAP (http://pgxn.org/dist/pgtap/) 8 | 2. pg_prove (http://search.cpan.org/~dwheeler/TAP-Parser-SourceHandler-pgTAP/bin/pg_prove) 9 | 10 | How to run 11 | ========= 12 | 1. Replace the password("__replace__appropriate_encryption_key__") 13 | which is written in the testcase as appropriate password before running the test. 14 | 2. Simply run a below command 15 | $ pg_prove -r -U -d -------------------------------------------------------------------------------- /SOURCES/test/t/DDL/alter_table.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | select cipher_key_disable_log(); 6 | select pgtde_begin_session('__replace__appropriate_encryption_key__'); 7 | select cipher_key_enable_log(); 8 | 9 | DROP TABLE IF EXISTS tdetest_enctxt_col; 10 | CREATE TABLE tdetest_enctxt_col ( 11 | c1 encrypt_text, 12 | set_type text, 13 | dropcol encrypt_text 14 | ); 15 | 16 | -- rename 17 | ALTER TABLE tdetest_enctxt_col RENAME COLUMN c1 TO newc1; 18 | SELECT has_column('tdetest_enctxt_col', 'newc1'); 19 | 20 | -- add column 21 | ALTER TABLE tdetest_enctxt_col ADD COLUMN addtxt encrypt_text; 22 | SELECT has_column('tdetest_enctxt_col'::name, 'addtxt'::name); 23 | 24 | -- drop column 25 | ALTER TABLE tdetest_enctxt_col DROP COLUMN dropcol RESTRICT; 26 | SELECT hasnt_column('tdetest_enctxt_col'::name, 'dropcol'::name); 27 | 28 | insert into tdetest_enctxt_col (set_type) values(text'plain text -> encrypt text'); 29 | -- alter column set data type 30 | ALTER TABLE tdetest_enctxt_col ALTER COLUMN set_type SET DATA TYPE encrypt_text; 31 | SELECT col_type_is('tdetest_enctxt_col'::name, 'set_type'::name, 'encrypt_text'); 32 | 33 | SELECT results_eq( 34 | 'SELECT set_type FROM tdetest_enctxt_col', 35 | ARRAY[encrypt_text'plain text -> encrypt text'] 36 | ); 37 | 38 | 39 | DROP TABLE IF EXISTS tdetest_encbytea_col; 40 | CREATE TABLE tdetest_encbytea_col ( 41 | c1 encrypt_bytea, 42 | set_type bytea, 43 | dropcol encrypt_bytea 44 | ); 45 | 46 | -- rename 47 | ALTER TABLE tdetest_encbytea_col RENAME COLUMN c1 TO newc1; 48 | SELECT has_column('tdetest_encbytea_col'::name, 'newc1'::name); 49 | 50 | -- add column 51 | ALTER TABLE tdetest_encbytea_col ADD COLUMN addbin encrypt_bytea; 52 | SELECT has_column('tdetest_encbytea_col'::name, 'addbin'::name); 53 | 54 | -- drop column 55 | ALTER TABLE tdetest_encbytea_col DROP COLUMN dropcol RESTRICT; 56 | SELECT hasnt_column('tdetest_encbytea_col'::name, 'dropcol'::name); 57 | 58 | insert into tdetest_encbytea_col (set_type) values(bytea'plain bytea -> encrypt bytea'); 59 | -- alter column set data type 60 | ALTER TABLE tdetest_encbytea_col ALTER COLUMN set_type SET DATA TYPE encrypt_bytea; 61 | SELECT col_type_is('tdetest_encbytea_col'::name, 'set_type'::name, 'encrypt_bytea'); 62 | 63 | SELECT results_eq( 64 | 'SELECT set_type FROM tdetest_encbytea_col', 65 | ARRAY[encrypt_bytea'plain bytea -> encrypt bytea'] 66 | ); 67 | 68 | 69 | select pgtde_end_session(); 70 | 71 | -- clean 72 | SELECT * FROM finish(); 73 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/DDL/create_index.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | 6 | DROP TABLE IF EXISTS tdetest_index_tbl; 7 | CREATE TABLE tdetest_index_tbl(txt encrypt_text, bytea encrypt_bytea); 8 | 9 | CREATE INDEX tdetest_idx_hash_txt ON tdetest_index_tbl USING hash (txt); 10 | CREATE INDEX tdetest_idx_hash_bytea ON tdetest_index_tbl USING hash (bytea); 11 | 12 | -- hash index for encrypt_text 13 | SELECT has_index('tdetest_index_tbl', 'tdetest_idx_hash_txt', 'txt'); 14 | -- hash index for encrypt_bytea 15 | SELECT has_index('tdetest_index_tbl', 'tdetest_idx_hash_bytea', 'bytea'); 16 | 17 | -- 42704 undefined_object 18 | -- cannot create btree, gist, gin index for encrypt_text 19 | SELECT throws_ok( 20 | 'CREATE INDEX tdetest_idx_btree_txt ON tdetest_index_tbl USING btree(txt)', 21 | '42704'); 22 | 23 | SELECT throws_ok( 24 | 'CREATE INDEX tdetest_idx_btree_txt ON tdetest_index_tbl USING gist(txt)', 25 | '42704'); 26 | 27 | SELECT throws_ok( 28 | 'CREATE INDEX tdetest_idx_btree_txt ON tdetest_index_tbl USING gin(txt)', 29 | '42704'); 30 | 31 | -- cannot create btree, gist, gin index for encrypt_bytea 32 | SELECT throws_ok( 33 | 'CREATE INDEX tdetest_idx_btree_bytea ON tdetest_index_tbl USING btree(bytea)', 34 | '42704'); 35 | 36 | SELECT throws_ok( 37 | 'CREATE INDEX tdetest_idx_btree_bytea ON tdetest_index_tbl USING gist(bytea)', 38 | '42704'); 39 | 40 | SELECT throws_ok( 41 | 'CREATE INDEX tdetest_idx_btree_bytea ON tdetest_index_tbl USING gin(bytea)', 42 | '42704'); 43 | 44 | SELECT * FROM finish(); 45 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/DDL/create_table.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | DROP TABLE IF EXISTS tdetest_enctxt_col; 6 | CREATE TABLE tdetest_enctxt_col ( 7 | c1 encrypt_text, 8 | c2 text 9 | ); 10 | 11 | 12 | 13 | DROP TABLE IF EXISTS tdetest_encbytea_col; 14 | CREATE TABLE tdetest_encbytea_col ( 15 | c1 encrypt_bytea, 16 | c2 bytea 17 | ); 18 | 19 | SELECT has_table('tdetest_enctxt_col'::name); 20 | SELECT has_table('tdetest_encbytea_col'::name); 21 | 22 | 23 | -- clean 24 | SELECT * FROM finish(); 25 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/DDL/reindex.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | 6 | DROP TABLE IF EXISTS tdetest_index_tbl; 7 | CREATE TABLE tdetest_index_txt(txt encrypt_text); 8 | CREATE TABLE tdetest_index_bytea (bytea encrypt_bytea); 9 | 10 | CREATE INDEX tdetest_idx_hash_txt ON tdetest_index_txt USING hash (txt); 11 | CREATE INDEX tdetest_idx_hash_bytea ON tdetest_index_bytea USING hash (bytea); 12 | 13 | select cipher_key_disable_log(); 14 | select pgtde_begin_session('__replace__appropriate_encryption_key__'); 15 | select cipher_key_enable_log(); 16 | 17 | INSERT INTO tdetest_index_txt SELECT (random()*10000)::text FROM generate_series(1,100); 18 | INSERT INTO tdetest_index_txt VALUES('test encrypt type'); 19 | INSERT INTO tdetest_index_txt VALUES(''); 20 | INSERT INTO tdetest_index_txt VALUES('new 21 | line'); 22 | INSERT INTO tdetest_index_txt VALUES('マルチバイト'); 23 | INSERT INTO tdetest_index_txt VALUES(' '); 24 | INSERT INTO tdetest_index_txt VALUES(' '); 25 | INSERT INTO tdetest_index_txt VALUES('!"#$%&''()'); 26 | INSERT INTO tdetest_index_txt VALUES(NULL); 27 | 28 | 29 | INSERT INTO tdetest_index_bytea SELECT (random()*10000)::text::bytea FROM generate_series(1,100); 30 | INSERT INTO tdetest_index_bytea VALUES(''); 31 | INSERT INTO tdetest_index_bytea VALUES('test encrypt type'); 32 | INSERT INTO tdetest_index_bytea VALUES('new 33 | line'); 34 | INSERT INTO tdetest_index_bytea VALUES('マルチバイト'); 35 | INSERT INTO tdetest_index_bytea VALUES(' '); 36 | INSERT INTO tdetest_index_bytea VALUES(' '); 37 | INSERT INTO tdetest_index_bytea VALUES('!"#$%&''()'); 38 | INSERT INTO tdetest_index_bytea VALUES(NULL); 39 | 40 | SELECT lives_ok('REINDEX INDEX tdetest_idx_hash_txt'); 41 | SELECT lives_ok('REINDEX INDEX tdetest_idx_hash_bytea'); 42 | 43 | SELECT lives_ok('REINDEX TABLE tdetest_index_txt'); 44 | SELECT lives_ok('REINDEX TABLE tdetest_index_bytea'); 45 | SELECT pgtde_end_session(); 46 | 47 | SELECT * FROM finish(); 48 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/cast/cast.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- 5 | -- INIT DATA 6 | -- 7 | DROP TABLE IF EXISTS c; 8 | DROP TABLE IF EXISTS e; 9 | DROP TABLE IF EXISTS p; 10 | 11 | CREATE TABLE c(id integer,c_bool boolean,c_bpchar bpchar(10),c_char "char",c_cidr cidr,c_inet inet,c_name name,c_pg_node_tree pg_node_tree,c_text text,c_varchar varchar,c_xml xml,c_regclass regclass); 12 | CREATE TABLE e(id serial,cname text,t text,b bytea, et encrypt_text, eb encrypt_bytea); 13 | CREATE TABLE p(id serial,cname text,t text,b bytea, et text, eb encrypt_bytea); 14 | 15 | INSERT INTO c SELECT generate_series(1,10); 16 | 17 | UPDATE c SET c_bool=true WHERE id=1; 18 | UPDATE c SET c_bool=false WHERE id=2; 19 | UPDATE c SET c_bool=NULL WHERE id=3; 20 | 21 | UPDATE c SET c_bpchar=E'\t\n ' WHERE id=1; 22 | UPDATE c SET c_bpchar=E'\t\n \=^+@}[*' WHERE id=2; 23 | UPDATE c SET c_bpchar='' WHERE id=3; 24 | UPDATE c SET c_bpchar=NULL WHERE id=4; 25 | 26 | UPDATE c SET c_char=E'\n' WHERE id=1; 27 | UPDATE c SET c_char='' WHERE id=2; 28 | UPDATE c SET c_char=NULL WHERE id=3; 29 | 30 | UPDATE c SET c_cidr='192.168.100.128/25' WHERE id=1; 31 | UPDATE c SET c_cidr='2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128' WHERE id=2; 32 | UPDATE c SET c_cidr=NULL WHERE id=3; 33 | 34 | UPDATE c SET c_inet='192.168.100.128/25' WHERE id=1; 35 | UPDATE c SET c_inet='2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128' WHERE id=2; 36 | UPDATE c SET c_inet=NULL WHERE id=3; 37 | 38 | UPDATE c SET c_name=E'\t\nTransparent Data Encryption for PostgreSQL\n\t******V1_0******\n' WHERE id=1; 39 | UPDATE c SET c_name='' WHERE id=2; 40 | UPDATE c SET c_name=NULL WHERE id=3; 41 | 42 | UPDATE c SET c_pg_node_tree=(SELECT ev_action FROM pg_rewrite WHERE rulename='pg_SETtings_u' limit 1) WHERE id=1; 43 | UPDATE c SET c_pg_node_tree=NULL WHERE id=2; 44 | 45 | UPDATE c SET c_text=(SELECT version()) WHERE id=1; 46 | UPDATE c SET c_text='' WHERE id=2; 47 | UPDATE c SET c_text=NULL WHERE id=3; 48 | 49 | UPDATE c SET c_varchar=(SELECT version()) WHERE id=1; 50 | UPDATE c SET c_varchar='' WHERE id=2; 51 | UPDATE c SET c_varchar=NULL WHERE id=3; 52 | 53 | -- This functionality requires the server to be built with libxml support 54 | UPDATE c SET c_xml=E' 55 | \n 56 | \n 57 | \n 58 | Result \n 59 | 0.00 \n 60 | 0.01 \n 61 | 1 \n 62 | 0 \n 63 | \n 64 | \n 65 | \n 66 | ' WHERE id=1; 67 | UPDATE c SET c_xml=NULL WHERE id=2; 68 | 69 | select cipher_key_disable_log(); 70 | select pgtde_begin_session('__replace__appropriate_encryption_key__'); 71 | select cipher_key_enable_log(); 72 | INSERT INTO e values(9999,'regclass','cipher_key_table',E'\x3141592abcdef','cipher_key_table',E'\x3141592abcdef'); 73 | INSERT INTO p values(9999,'regclass','cipher_key_table',E'\x3141592abcdef','cipher_key_table',E'\x3141592abcdef'); 74 | -- test start 75 | 76 | --CAST(plain type AS encrypt_text) 77 | INSERT INTO e (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=1; 78 | INSERT INTO e (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=2; 79 | INSERT INTO e (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=3; 80 | 81 | INSERT INTO e (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=1; 82 | INSERT INTO e (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=2; 83 | INSERT INTO e (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=3; 84 | INSERT INTO e (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=4; 85 | 86 | INSERT INTO e (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=1; 87 | INSERT INTO e (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=2; 88 | INSERT INTO e (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=3; 89 | 90 | INSERT INTO e (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=1; 91 | INSERT INTO e (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=2; 92 | INSERT INTO e (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=3; 93 | 94 | INSERT INTO e (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=1; 95 | INSERT INTO e (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=2; 96 | INSERT INTO e (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=3; 97 | 98 | INSERT INTO e (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=1; 99 | INSERT INTO e (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=2; 100 | INSERT INTO e (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=3; 101 | 102 | INSERT INTO e (cname,t,et) SELECT 'pg_node_tree',c_pg_node_tree,c_pg_node_tree FROM c WHERE id=1; 103 | INSERT INTO e (cname,t,et) SELECT 'pg_node_tree',c_pg_node_tree,c_pg_node_tree FROM c WHERE id=2; 104 | 105 | INSERT INTO e (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=1; 106 | INSERT INTO e (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=2; 107 | INSERT INTO e (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=3; 108 | 109 | INSERT INTO e (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=1; 110 | INSERT INTO e (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=2; 111 | INSERT INTO e (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=3; 112 | 113 | INSERT INTO e (cname,t,et) SELECT 'xml',c_xml,c_xml FROM c WHERE id=1; 114 | INSERT INTO e (cname,t,et) SELECT 'xml',c_xml,c_xml FROM c WHERE id=2; 115 | 116 | INSERT INTO e (cname,t,et) SELECT 'encrypt_bytea',eb,eb FROM e WHERE id=9999; 117 | 118 | -- CAST(plain type AS text) 119 | INSERT INTO p (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=1; 120 | INSERT INTO p (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=2; 121 | INSERT INTO p (cname,t,et) SELECT 'bool',c_bool,c_bool FROM c WHERE id=3; 122 | 123 | INSERT INTO p (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=1; 124 | INSERT INTO p (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=2; 125 | INSERT INTO p (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=3; 126 | INSERT INTO p (cname,t,et) SELECT 'bpchar',c_bpchar,c_bpchar FROM c WHERE id=4; 127 | 128 | INSERT INTO p (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=1; 129 | INSERT INTO p (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=2; 130 | INSERT INTO p (cname,t,et) SELECT 'char',c_char,c_char FROM c WHERE id=3; 131 | 132 | INSERT INTO p (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=1; 133 | INSERT INTO p (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=2; 134 | INSERT INTO p (cname,t,et) SELECT 'cidr',c_cidr,c_cidr FROM c WHERE id=3; 135 | 136 | INSERT INTO p (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=1; 137 | INSERT INTO p (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=2; 138 | INSERT INTO p (cname,t,et) SELECT 'inet',c_inet,c_inet FROM c WHERE id=3; 139 | 140 | INSERT INTO p (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=1; 141 | INSERT INTO p (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=2; 142 | INSERT INTO p (cname,t,et) SELECT 'name',c_name,c_name FROM c WHERE id=3; 143 | 144 | INSERT INTO p (cname,t,et) SELECT 'pg_node_tree',c_pg_node_tree,c_pg_node_tree FROM c WHERE id=1; 145 | INSERT INTO p (cname,t,et) SELECT 'pg_node_tree',c_pg_node_tree,c_pg_node_tree FROM c WHERE id=2; 146 | 147 | INSERT INTO p (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=1; 148 | INSERT INTO p (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=2; 149 | INSERT INTO p (cname,t,et) SELECT 'text',c_text,c_text FROM c WHERE id=3; 150 | 151 | INSERT INTO p (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=1; 152 | INSERT INTO p (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=2; 153 | INSERT INTO p (cname,t,et) SELECT 'varchar',c_varchar,c_varchar FROM c WHERE id=3; 154 | 155 | INSERT INTO p (cname,t,et) SELECT 'xml',c_xml,c_xml FROM c WHERE id=1; 156 | INSERT INTO p (cname,t,et) SELECT 'xml',c_xml,c_xml FROM c WHERE id=2; 157 | 158 | INSERT INTO p (cname,t,et) SELECT 'encrypt_bytea',eb,eb FROM p WHERE id=9999; 159 | 160 | --RESULT CHECK (TRUE EXCEPT NULL=NULL(=NULL)) 161 | SELECT results_eq( 162 | 'SELECT id,cname,t=et AS result FROM e ORDER BY id', 163 | 'SELECT id,cname,t=et AS result FROM p ORDER BY id'); 164 | 165 | 166 | -- CAST(encrypt_text AS plain type) 167 | DROP TABLE IF EXISTS c2; 168 | CREATE TEMP TABLE c2(id serial,cname text,c_bool boolean,c_bpchar bpchar(10),c_char "char",c_cidr cidr,c_inet inet,c_name name,c_pg_node_tree pg_node_tree,c_text text,c_varchar varchar,c_xml xml,c_regclass regclass,c2_bool boolean,c2_bpchar bpchar(10),c2_char "char",c2_cidr cidr,c2_inet inet,c2_name name,c2_pg_node_tree pg_node_tree,c2_text text,c2_varchar varchar,c2_xml xml,c2_regclass regclass); 169 | 170 | INSERT INTO c2 (cname,c_bpchar,c2_bpchar) SELECT cname,t,et FROM e WHERE cname='bpchar'; 171 | INSERT INTO c2 (cname,c_char,c2_char) SELECT cname,t,et FROM e WHERE cname='char'; 172 | INSERT INTO c2 (cname,c_name,c2_name) SELECT cname,t,et FROM e WHERE cname='name'; 173 | INSERT INTO c2 (cname,c_name,c2_name) SELECT 'name', 174 | E'\t\nTransparent Data Encryption for PostgreSQL\n\t******V1_0******over64byte\n', 175 | E'\t\nTransparent Data Encryption for PostgreSQL\n\t******V1_0******over64byte\n'; -- ### special case 176 | INSERT INTO c2 (cname,c_regclass,c2_regclass) SELECT cname,t,et FROM e WHERE cname='regclass'; 177 | INSERT INTO c2 (cname,c_text,c2_text) SELECT cname,t,et FROM e WHERE cname='text'; 178 | INSERT INTO c2 (cname,c_varchar,c2_varchar) SELECT cname,t,et FROM e WHERE cname='varchar'; 179 | SELECT throws_ok('INSERT INTO c2 (cname,c_xml,c2_xml) SELECT cname,t,et FROM e WHERE cname=''xml'''); 180 | INSERT INTO c2 (cname,c_xml,c2_xml) SELECT cname,t::xml,et::xml FROM e WHERE cname='xml'; 181 | 182 | --RESULT CHECK(TRUE) 183 | SELECT c_bpchar=c2_bpchar AS result FROM c2 WHERE cname='bpchar'; 184 | SELECT c_char=c2_char AS result FROM c2 WHERE cname='char'; 185 | SELECT c_name=c2_name AS result FROM c2 WHERE cname='name'; 186 | SELECT c_regclass=c2_regclass AS result FROM c2 WHERE cname='regclass'; 187 | SELECT c_text=c2_text AS result FROM c2 WHERE cname='text'; 188 | SELECT c_varchar=c2_varchar AS result FROM c2 WHERE cname='varchar'; 189 | SELECT c_xml::text=c2_xml::text AS result FROM c2 WHERE cname='xml'; 190 | 191 | 192 | DROP TABLE IF EXISTS e2; 193 | CREATE TEMP TABLE e2(id integer,cname text,t text,b text,et encrypt_text,eb encrypt_text); 194 | INSERT INTO e2 SELECT * FROM e WHERE id=9999; 195 | 196 | INSERT INTO e (cname,b,eb) SELECT 'encrypt_text',b::bytea,eb::encrypt_bytea FROM e2 WHERE id=9999; 197 | INSERT INTO p (cname,b,eb) SELECT 'encrypt_text',b::bytea,eb::encrypt_bytea FROM e2 WHERE id=9999; 198 | 199 | --RESULT CHECK (TRUE) 200 | SELECT results_eq( 201 | 'SELECT id,cname,b=eb FROM e WHERE cname=''encrypt_text''', 202 | 'SELECT id,cname,b=eb FROM p WHERE cname=''encrypt_text'''); 203 | 204 | --IMPLICIT CAST 205 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_bool::encrypt_text=c_bool FROM c' , 42883); 206 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_bool::text=c_bool FROM c' , 42883); 207 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_cidr::encrypt_text=c_cidr FROM c' , 42883); 208 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_cidr::text=c_cidr FROM c' , 42883); 209 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_inet::encrypt_text=c_inet FROM c' , 42883); 210 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_inet::text=c_inet FROM c' , 42883); 211 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_regclass::encrypt_text=c_regclass FROM c', 42883); 212 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_regclass::text=c_regclass FROM c' , 42883); 213 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_xml::encrypt_text=c_xml FROM c' , 42883); 214 | SELECT throws_ok('EXPLAIN VERBOSE SELECT c_xml::text=c_xml FROM c' , 42883); 215 | 216 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_bpchar::encrypt_text=c_bpchar FROM c'); 217 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_char::encrypt_text=c_char FROM c'); 218 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_name::encrypt_text=c_name FROM c'); 219 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_pg_node_tree::encrypt_text=c_pg_node_tree FROM c'); 220 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_text::encrypt_text=c_text FROM c'); 221 | SELECT lives_ok('EXPLAIN VERBOSE SELECT c_varchar::encrypt_text=c_varchar FROM c'); 222 | 223 | --CAST(plain type AS encrypt_bytea) 224 | INSERT INTO e (cname,b,eb) SELECT 'encrypt_bytea',b,b FROM e WHERE id=9999; 225 | INSERT INTO e (cname,b,eb) SELECT 'encrypt_bytea',NULL::bytea,NULL::bytea FROM e WHERE id=9999; 226 | INSERT INTO e (cname,b,eb) SELECT 'encrypt_bytea',eb,eb FROM e WHERE id=9999; 227 | 228 | INSERT INTO p (cname,b,eb) SELECT 'encrypt_bytea',b,b FROM e WHERE id=9999; 229 | INSERT INTO p (cname,b,eb) SELECT 'encrypt_bytea',NULL::bytea,NULL::bytea FROM e WHERE id=9999; 230 | INSERT INTO p (cname,b,eb) SELECT 'encrypt_bytea',eb,eb FROM e WHERE id=9999; 231 | 232 | --RESULT CHECK (TRUE) 233 | SELECT results_eq( 234 | 'SELECT id,cname,b=eb FROM e WHERE cname=''encrypt_bytea''', 235 | 'SELECT id,cname,b=eb FROM p WHERE cname=''encrypt_bytea'''); 236 | 237 | EXPLAIN VERBOSE SELECT b=eb FROM e; 238 | 239 | 240 | SELECT pgtde_end_session(); 241 | 242 | -- clean 243 | SELECT * FROM finish(); 244 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/encbytea/aggregation/aggregate_bytea.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | select cipher_key_disable_log(); 6 | select pgtde_begin_session('__replace__appropriate_encryption_key__'); 7 | select cipher_key_enable_log(); 8 | 9 | DROP TABLE IF EXISTS tdetest_bin; 10 | DROP TABLE IF EXISTS tdetest_encbin; 11 | 12 | CREATE TABLE tdetest_bin(id serial PRIMARY KEY, c1 bytea); 13 | CREATE TABLE tdetest_encbin(id serial PRIMARY KEY, c1 encrypt_bytea); 14 | 15 | INSERT INTO tdetest_bin (c1) SELECT (random()*10000)::text::bytea FROM generate_series(1,100); 16 | INSERT INTO tdetest_bin (c1) VALUES('test encrypt type'); 17 | INSERT INTO tdetest_bin (c1) VALUES(''); 18 | INSERT INTO tdetest_bin (c1) VALUES('new 19 | line'); 20 | INSERT INTO tdetest_bin (c1) VALUES('マルチバイト'); 21 | INSERT INTO tdetest_bin (c1) VALUES(' '); 22 | INSERT INTO tdetest_bin (c1) VALUES(' '); 23 | INSERT INTO tdetest_bin (c1) VALUES('!"#$%&''()'); 24 | INSERT INTO tdetest_bin (c1) VALUES(NULL); 25 | 26 | INSERT INTO tdetest_encbin (c1) SELECT c1 FROM tdetest_bin; 27 | 28 | 29 | 30 | SELECT results_eq('SELECT count(c1) FROM tdetest_bin', 31 | 'SELECT count(c1) FROM tdetest_encbin'); 32 | 33 | SELECT results_eq('SELECT string_agg(c1,''--'') FROM tdetest_bin', 34 | 'SELECT string_agg(c1,''--'') FROM tdetest_encbin'); 35 | 36 | SELECT results_eq('SELECT count(c1) FROM tdetest_bin', 37 | 'SELECT count(c1) FROM tdetest_encbin'); 38 | 39 | 40 | SELECT pgtde_end_session(); 41 | 42 | -- clean 43 | SELECT * FROM finish(); 44 | ROLLBACK; -------------------------------------------------------------------------------- /SOURCES/test/t/encbytea/cmp/cmp_encbytea.pg: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | SELECT * FROM no_plan(); 3 | 4 | -- start test 5 | select cipher_key_disable_log(); 6 | select pgtde_begin_session('__replace__appropriate_encryption_key__'); 7 | select cipher_key_enable_log(); 8 | 9 | DROP TABLE IF EXISTS tdetest_bin; 10 | DROP TABLE IF EXISTS tdetest_encbin; 11 | 12 | CREATE TABLE tdetest_bin(id serial PRIMARY KEY, c1 bytea); 13 | CREATE TABLE tdetest_encbin(id serial PRIMARY KEY, c1 encrypt_bytea); 14 | 15 | INSERT INTO tdetest_bin (c1) SELECT md5(clock_timestamp()::text)::bytea FROM generate_series(1,30); 16 | INSERT INTO tdetest_bin (c1) VALUES(NULL); 17 | 18 | INSERT INTO tdetest_encbin SELECT * FROM tdetest_bin; 19 | 20 | -- eq 21 | SELECT results_eq('SELECT a.c1=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 22 | 'SELECT a.c1=b.c1 FROM tdetest_encbin a, tdetest_encbin b ORDER BY a.id'); 23 | SELECT results_eq('SELECT a.c1=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 24 | 'SELECT a.c1=b.c1 FROM tdetest_encbin a, tdetest_bin b ORDER BY a.id'); 25 | -- ne 26 | SELECT results_eq('SELECT a.c1<>b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 27 | 'SELECT a.c1<>b.c1 FROM tdetest_encbin a, tdetest_encbin b ORDER BY a.id'); 28 | SELECT results_eq('SELECT a.c1<>b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 29 | 'SELECT a.c1<>b.c1 FROM tdetest_encbin a, tdetest_bin b ORDER BY a.id'); 30 | -- ge 31 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 32 | 'SELECT a.c1>=b.c1 FROM tdetest_encbin a, tdetest_encbin b ORDER BY a.id'); 33 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 34 | 'SELECT a.c1>=b.c1 FROM tdetest_encbin a, tdetest_bin b ORDER BY a.id'); 35 | 36 | -- gt 37 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 38 | 'SELECT a.c1>b.c1 FROM tdetest_encbin a, tdetest_encbin b ORDER BY a.id'); 39 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 40 | 'SELECT a.c1>b.c1 FROM tdetest_encbin a, tdetest_bin b ORDER BY a.id'); 41 | 42 | -- le 43 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 44 | 'SELECT a.c1<=b.c1 FROM tdetest_encbin a, tdetest_encbin b ORDER BY a.id'); 45 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_bin a, tdetest_bin b ORDER BY a.id', 46 | 'SELECT a.c1<=b.c1 FROM tdetest_encbin a, tdetest_bin b ORDER BY a.id'); 47 | 48 | -- lt 49 | SELECT results_eq('SELECT a.c1b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 37 | 'SELECT a.c1<>b.c1 FROM tdetest_enctxt a, tdetest_enctxt b ORDER BY a.id'); 38 | SELECT results_eq('SELECT a.c1<>b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 39 | 'SELECT a.c1<>b.c1 FROM tdetest_enctxt a, tdetest_txt b ORDER BY a.id'); 40 | -- ge 41 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 42 | 'SELECT a.c1>=b.c1 FROM tdetest_enctxt a, tdetest_enctxt b ORDER BY a.id'); 43 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 44 | 'SELECT a.c1>=b.c1 FROM tdetest_enctxt a, tdetest_txt b ORDER BY a.id'); 45 | 46 | -- gt 47 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 48 | 'SELECT a.c1>b.c1 FROM tdetest_enctxt a, tdetest_enctxt b ORDER BY a.id'); 49 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 50 | 'SELECT a.c1>b.c1 FROM tdetest_enctxt a, tdetest_txt b ORDER BY a.id'); 51 | 52 | -- le 53 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 54 | 'SELECT a.c1<=b.c1 FROM tdetest_enctxt a, tdetest_enctxt b ORDER BY a.id'); 55 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_txt a, tdetest_txt b ORDER BY a.id', 56 | 'SELECT a.c1<=b.c1 FROM tdetest_enctxt a, tdetest_txt b ORDER BY a.id'); 57 | 58 | -- lt 59 | SELECT results_eq('SELECT a.c1b.c1 FROM tdetest_txt a, tdetest_char b ORDER BY a.id', 84 | 'SELECT a.c1<>b.c1 FROM tdetest_enctxt a, tdetest_char b ORDER BY a.id'); 85 | SELECT results_eq('SELECT a.c1<>b.c1 FROM tdetest_txt a, tdetest_varchar b ORDER BY a.id', 86 | 'SELECT a.c1<>b.c1 FROM tdetest_enctxt a, tdetest_varchar b ORDER BY a.id'); 87 | SELECT results_eq('SELECT a.c1<>b.c1 FROM tdetest_txt a, tdetest_name b ORDER BY a.id', 88 | 'SELECT a.c1<>b.c1 FROM tdetest_enctxt a, tdetest_name b ORDER BY a.id'); 89 | -- ge 90 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_txt a, tdetest_char b ORDER BY a.id', 91 | 'SELECT a.c1>=b.c1 FROM tdetest_enctxt a, tdetest_char b ORDER BY a.id'); 92 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_txt a, tdetest_varchar b ORDER BY a.id', 93 | 'SELECT a.c1>=b.c1 FROM tdetest_enctxt a, tdetest_varchar b ORDER BY a.id'); 94 | SELECT results_eq('SELECT a.c1>=b.c1 FROM tdetest_txt a, tdetest_name b ORDER BY a.id', 95 | 'SELECT a.c1>=b.c1 FROM tdetest_enctxt a, tdetest_name b ORDER BY a.id'); 96 | 97 | -- gt 98 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_txt a, tdetest_char b ORDER BY a.id', 99 | 'SELECT a.c1>b.c1 FROM tdetest_enctxt a, tdetest_char b ORDER BY a.id'); 100 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_txt a, tdetest_varchar b ORDER BY a.id', 101 | 'SELECT a.c1>b.c1 FROM tdetest_enctxt a, tdetest_varchar b ORDER BY a.id'); 102 | SELECT results_eq('SELECT a.c1>b.c1 FROM tdetest_txt a, tdetest_name b ORDER BY a.id', 103 | 'SELECT a.c1>b.c1 FROM tdetest_enctxt a, tdetest_name b ORDER BY a.id'); 104 | 105 | -- le 106 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_txt a, tdetest_char b ORDER BY a.id', 107 | 'SELECT a.c1<=b.c1 FROM tdetest_enctxt a, tdetest_char b ORDER BY a.id'); 108 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_txt a, tdetest_varchar b ORDER BY a.id', 109 | 'SELECT a.c1<=b.c1 FROM tdetest_enctxt a, tdetest_varchar b ORDER BY a.id'); 110 | SELECT results_eq('SELECT a.c1<=b.c1 FROM tdetest_txt a, tdetest_name b ORDER BY a.id', 111 | 'SELECT a.c1<=b.c1 FROM tdetest_enctxt a, tdetest_name b ORDER BY a.id'); 112 | 113 | -- lt 114 | SELECT results_eq('SELECT a.c1 -Fc 22 | 23 | 3. Make a restore list from dumpfile 24 | $ pg_restore -l > 25 | $ psql -F ' ' -d << EOF | grep -E [0-9]+ > 26 | \t 27 | \a 28 | SELECT a.oid, 'OPERATOR', nspname , oprname, rolname 29 | FROM pg_operator a JOIN pg_authid b ON a.oprowner=b.oid 30 | JOIN pg_namespace c ON c.oid=a.oprnamespace 31 | WHERE a.oprcode in (select oid from pg_proc where probin like '%data_encryption.so'); 32 | EOF 33 | $ grep -v -f $TDEHOME/SOURCES/lib/upgrade/installed_list_fe_.txt -f > 34 | 35 | 4. Uninstall old version of tdeforpg 36 | $ sh $TDEHOME/SOURCES/bin/cipher_setup.sh $PGHOME 37 | Transparent data encryption feature setup script 38 | Please select from the setup menu below 39 | Transparent data encryption feature setup menu 40 | 1: activate the transparent data encryption feature 41 | 2: inactivate the transparent data encryption feature 42 | select menu [1 - 2] > 2 43 | Please enter database server port to connect : 44 | Please enter database user name to connect : 45 | Please enter password for authentication : 46 | Please enter database name to connect : 47 | INFO: The transparent data encryption feature has been inactivated 48 | 49 | 5. Drop the database 50 | $ dropdb 51 | 52 | 6. Recreate a database which you are dropped just before 53 | $ createdb 54 | 55 | 7. Delete old shared object file 56 | $ sudo rm /usr/lib64/data_encryption.so 57 | 58 | 8. Building and install new tdeforpg to database 59 | Please refer to the INSTALL-NOTE for more details. 60 | 61 | 9. Restore database using pg_restore 62 | $ PGOPTIONS="-c encrypt.enable=off" pg_restore -d -L -e 63 | 64 | -------------------------------------------------------------------------------- /docs/images/cipher_setup_FE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/docs/images/cipher_setup_FE.png -------------------------------------------------------------------------------- /docs/images/install1_start_FE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/docs/images/install1_start_FE.png -------------------------------------------------------------------------------- /docs/images/install4_finish_FE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/docs/images/install4_finish_FE.png -------------------------------------------------------------------------------- /docs/images/pgtde_regist_FE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nec-postgres/tdeforpg/63735cf699e694569b9dcc9eb774ccd18129e2c4/docs/images/pgtde_regist_FE.png -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | 以下のTransparent Data Encryption for PostgreSQL Free Editionのマニュアルを参照してください。 2 | 3 | https://github.com/nec-postgres/tdeforpg/wiki/Manual(JA) --------------------------------------------------------------------------------