github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_encryption.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "bytes" 18 "compress/zlib" 19 "crypto/aes" 20 "crypto/md5" 21 "crypto/rand" 22 "crypto/sha1" 23 "crypto/sha256" 24 "crypto/sha512" 25 "encoding/binary" 26 "fmt" 27 "hash" 28 "io" 29 "strings" 30 31 "github.com/whtcorpsinc/errors" 32 "github.com/whtcorpsinc/BerolinaSQL/auth" 33 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 34 "github.com/whtcorpsinc/milevadb/stochastikctx" 35 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 36 "github.com/whtcorpsinc/milevadb/types" 37 "github.com/whtcorpsinc/milevadb/soliton/chunk" 38 "github.com/whtcorpsinc/milevadb/soliton/encrypt" 39 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 40 ) 41 42 var ( 43 _ functionClass = &aesDecryptFunctionClass{} 44 _ functionClass = &aesEncryptFunctionClass{} 45 _ functionClass = &compressFunctionClass{} 46 _ functionClass = &decodeFunctionClass{} 47 _ functionClass = &desDecryptFunctionClass{} 48 _ functionClass = &desEncryptFunctionClass{} 49 _ functionClass = &encodeFunctionClass{} 50 _ functionClass = &encryptFunctionClass{} 51 _ functionClass = &md5FunctionClass{} 52 _ functionClass = &oldPasswordFunctionClass{} 53 _ functionClass = &passwordFunctionClass{} 54 _ functionClass = &randomBytesFunctionClass{} 55 _ functionClass = &sha1FunctionClass{} 56 _ functionClass = &sha2FunctionClass{} 57 _ functionClass = &uncompressFunctionClass{} 58 _ functionClass = &uncompressedLengthFunctionClass{} 59 _ functionClass = &validatePasswordStrengthFunctionClass{} 60 ) 61 62 var ( 63 _ builtinFunc = &builtinAesDecryptSig{} 64 _ builtinFunc = &builtinAesDecryptIVSig{} 65 _ builtinFunc = &builtinAesEncryptSig{} 66 _ builtinFunc = &builtinAesEncryptIVSig{} 67 _ builtinFunc = &builtinCompressSig{} 68 _ builtinFunc = &builtinMD5Sig{} 69 _ builtinFunc = &builtinPasswordSig{} 70 _ builtinFunc = &builtinRandomBytesSig{} 71 _ builtinFunc = &builtinSHA1Sig{} 72 _ builtinFunc = &builtinSHA2Sig{} 73 _ builtinFunc = &builtinUncompressSig{} 74 _ builtinFunc = &builtinUncompressedLengthSig{} 75 ) 76 77 // aesModeAttr indicates that the key length and iv attribute for specific block_encryption_mode. 78 // keySize is the key length in bits and mode is the encryption mode. 79 // ivRequired indicates that initialization vector is required or not. 80 type aesModeAttr struct { 81 modeName string 82 keySize int 83 ivRequired bool 84 } 85 86 var aesModes = map[string]*aesModeAttr{ 87 //TODO support more modes, permitted mode values are: ECB, CBC, CFB1, CFB8, CFB128, OFB 88 "aes-128-ecb": {"ecb", 16, false}, 89 "aes-192-ecb": {"ecb", 24, false}, 90 "aes-256-ecb": {"ecb", 32, false}, 91 "aes-128-cbc": {"cbc", 16, true}, 92 "aes-192-cbc": {"cbc", 24, true}, 93 "aes-256-cbc": {"cbc", 32, true}, 94 "aes-128-ofb": {"ofb", 16, true}, 95 "aes-192-ofb": {"ofb", 24, true}, 96 "aes-256-ofb": {"ofb", 32, true}, 97 "aes-128-cfb": {"cfb", 16, true}, 98 "aes-192-cfb": {"cfb", 24, true}, 99 "aes-256-cfb": {"cfb", 32, true}, 100 } 101 102 type aesDecryptFunctionClass struct { 103 baseFunctionClass 104 } 105 106 func (c *aesDecryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 107 if err := c.verifyArgs(args); err != nil { 108 return nil, c.verifyArgs(args) 109 } 110 argTps := make([]types.EvalType, 0, len(args)) 111 for range args { 112 argTps = append(argTps, types.ETString) 113 } 114 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argTps...) 115 if err != nil { 116 return nil, err 117 } 118 bf.tp.Flen = args[0].GetType().Flen // At most. 119 types.SetBinChsClnFlag(bf.tp) 120 121 blockMode, _ := ctx.GetStochastikVars().GetSystemVar(variable.BlockEncryptionMode) 122 mode, exists := aesModes[strings.ToLower(blockMode)] 123 if !exists { 124 return nil, errors.Errorf("unsupported causet encryption mode - %v", blockMode) 125 } 126 if mode.ivRequired { 127 if len(args) != 3 { 128 return nil, ErrIncorrectParameterCount.GenWithStackByArgs("aes_decrypt") 129 } 130 sig := &builtinAesDecryptIVSig{bf, mode} 131 sig.setPbCode(fidelpb.ScalarFuncSig_AesDecryptIV) 132 return sig, nil 133 } 134 sig := &builtinAesDecryptSig{bf, mode} 135 sig.setPbCode(fidelpb.ScalarFuncSig_AesDecrypt) 136 return sig, nil 137 } 138 139 type builtinAesDecryptSig struct { 140 baseBuiltinFunc 141 *aesModeAttr 142 } 143 144 func (b *builtinAesDecryptSig) Clone() builtinFunc { 145 newSig := &builtinAesDecryptSig{} 146 newSig.cloneFrom(&b.baseBuiltinFunc) 147 newSig.aesModeAttr = b.aesModeAttr 148 return newSig 149 } 150 151 // evalString evals AES_DECRYPT(crypt_str, key_key). 152 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 153 func (b *builtinAesDecryptSig) evalString(event chunk.Event) (string, bool, error) { 154 // According to doc: If either function argument is NULL, the function returns NULL. 155 cryptStr, isNull, err := b.args[0].EvalString(b.ctx, event) 156 if isNull || err != nil { 157 return "", true, err 158 } 159 keyStr, isNull, err := b.args[1].EvalString(b.ctx, event) 160 if isNull || err != nil { 161 return "", true, err 162 } 163 if !b.ivRequired && len(b.args) == 3 { 164 // For modes that do not require init_vector, it is ignored and a warning is generated if it is specified. 165 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV")) 166 } 167 168 key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize) 169 var plainText []byte 170 switch b.modeName { 171 case "ecb": 172 plainText, err = encrypt.AESDecryptWithECB([]byte(cryptStr), key) 173 default: 174 return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 175 } 176 if err != nil { 177 return "", true, nil 178 } 179 return string(plainText), false, nil 180 } 181 182 type builtinAesDecryptIVSig struct { 183 baseBuiltinFunc 184 *aesModeAttr 185 } 186 187 func (b *builtinAesDecryptIVSig) Clone() builtinFunc { 188 newSig := &builtinAesDecryptIVSig{} 189 newSig.cloneFrom(&b.baseBuiltinFunc) 190 newSig.aesModeAttr = b.aesModeAttr 191 return newSig 192 } 193 194 // evalString evals AES_DECRYPT(crypt_str, key_key, iv). 195 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 196 func (b *builtinAesDecryptIVSig) evalString(event chunk.Event) (string, bool, error) { 197 // According to doc: If either function argument is NULL, the function returns NULL. 198 cryptStr, isNull, err := b.args[0].EvalString(b.ctx, event) 199 if isNull || err != nil { 200 return "", true, err 201 } 202 203 keyStr, isNull, err := b.args[1].EvalString(b.ctx, event) 204 if isNull || err != nil { 205 return "", true, err 206 } 207 208 iv, isNull, err := b.args[2].EvalString(b.ctx, event) 209 if isNull || err != nil { 210 return "", true, err 211 } 212 if len(iv) < aes.BlockSize { 213 return "", true, errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_decrypt is too short. Must be at least %d bytes long", aes.BlockSize) 214 } 215 // init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored) 216 iv = iv[0:aes.BlockSize] 217 218 key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize) 219 var plainText []byte 220 switch b.modeName { 221 case "cbc": 222 plainText, err = encrypt.AESDecryptWithCBC([]byte(cryptStr), key, []byte(iv)) 223 case "ofb": 224 plainText, err = encrypt.AESDecryptWithOFB([]byte(cryptStr), key, []byte(iv)) 225 case "cfb": 226 plainText, err = encrypt.AESDecryptWithCFB([]byte(cryptStr), key, []byte(iv)) 227 default: 228 return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 229 } 230 if err != nil { 231 return "", true, nil 232 } 233 return string(plainText), false, nil 234 } 235 236 type aesEncryptFunctionClass struct { 237 baseFunctionClass 238 } 239 240 func (c *aesEncryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 241 if err := c.verifyArgs(args); err != nil { 242 return nil, c.verifyArgs(args) 243 } 244 argTps := make([]types.EvalType, 0, len(args)) 245 for range args { 246 argTps = append(argTps, types.ETString) 247 } 248 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argTps...) 249 if err != nil { 250 return nil, err 251 } 252 bf.tp.Flen = aes.BlockSize * (args[0].GetType().Flen/aes.BlockSize + 1) // At most. 253 types.SetBinChsClnFlag(bf.tp) 254 255 blockMode, _ := ctx.GetStochastikVars().GetSystemVar(variable.BlockEncryptionMode) 256 mode, exists := aesModes[strings.ToLower(blockMode)] 257 if !exists { 258 return nil, errors.Errorf("unsupported causet encryption mode - %v", blockMode) 259 } 260 if mode.ivRequired { 261 if len(args) != 3 { 262 return nil, ErrIncorrectParameterCount.GenWithStackByArgs("aes_encrypt") 263 } 264 sig := &builtinAesEncryptIVSig{bf, mode} 265 sig.setPbCode(fidelpb.ScalarFuncSig_AesEncryptIV) 266 return sig, nil 267 } 268 sig := &builtinAesEncryptSig{bf, mode} 269 sig.setPbCode(fidelpb.ScalarFuncSig_AesEncrypt) 270 return sig, nil 271 } 272 273 type builtinAesEncryptSig struct { 274 baseBuiltinFunc 275 *aesModeAttr 276 } 277 278 func (b *builtinAesEncryptSig) Clone() builtinFunc { 279 newSig := &builtinAesEncryptSig{} 280 newSig.cloneFrom(&b.baseBuiltinFunc) 281 newSig.aesModeAttr = b.aesModeAttr 282 return newSig 283 } 284 285 // evalString evals AES_ENCRYPT(str, key_str). 286 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 287 func (b *builtinAesEncryptSig) evalString(event chunk.Event) (string, bool, error) { 288 // According to doc: If either function argument is NULL, the function returns NULL. 289 str, isNull, err := b.args[0].EvalString(b.ctx, event) 290 if isNull || err != nil { 291 return "", true, err 292 } 293 keyStr, isNull, err := b.args[1].EvalString(b.ctx, event) 294 if isNull || err != nil { 295 return "", true, err 296 } 297 if !b.ivRequired && len(b.args) == 3 { 298 // For modes that do not require init_vector, it is ignored and a warning is generated if it is specified. 299 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV")) 300 } 301 302 key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize) 303 var cipherText []byte 304 switch b.modeName { 305 case "ecb": 306 cipherText, err = encrypt.AESEncryptWithECB([]byte(str), key) 307 default: 308 return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 309 } 310 if err != nil { 311 return "", true, nil 312 } 313 return string(cipherText), false, nil 314 } 315 316 type builtinAesEncryptIVSig struct { 317 baseBuiltinFunc 318 *aesModeAttr 319 } 320 321 func (b *builtinAesEncryptIVSig) Clone() builtinFunc { 322 newSig := &builtinAesEncryptIVSig{} 323 newSig.cloneFrom(&b.baseBuiltinFunc) 324 newSig.aesModeAttr = b.aesModeAttr 325 return newSig 326 } 327 328 // evalString evals AES_ENCRYPT(str, key_str, iv). 329 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 330 func (b *builtinAesEncryptIVSig) evalString(event chunk.Event) (string, bool, error) { 331 // According to doc: If either function argument is NULL, the function returns NULL. 332 str, isNull, err := b.args[0].EvalString(b.ctx, event) 333 if isNull || err != nil { 334 return "", true, err 335 } 336 337 keyStr, isNull, err := b.args[1].EvalString(b.ctx, event) 338 if isNull || err != nil { 339 return "", true, err 340 } 341 342 iv, isNull, err := b.args[2].EvalString(b.ctx, event) 343 if isNull || err != nil { 344 return "", true, err 345 } 346 if len(iv) < aes.BlockSize { 347 return "", true, errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_encrypt is too short. Must be at least %d bytes long", aes.BlockSize) 348 } 349 // init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored) 350 iv = iv[0:aes.BlockSize] 351 352 key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize) 353 var cipherText []byte 354 switch b.modeName { 355 case "cbc": 356 cipherText, err = encrypt.AESEncryptWithCBC([]byte(str), key, []byte(iv)) 357 case "ofb": 358 cipherText, err = encrypt.AESEncryptWithOFB([]byte(str), key, []byte(iv)) 359 case "cfb": 360 cipherText, err = encrypt.AESEncryptWithCFB([]byte(str), key, []byte(iv)) 361 default: 362 return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 363 } 364 if err != nil { 365 return "", true, nil 366 } 367 return string(cipherText), false, nil 368 } 369 370 type decodeFunctionClass struct { 371 baseFunctionClass 372 } 373 374 func (c *decodeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 375 if err := c.verifyArgs(args); err != nil { 376 return nil, err 377 } 378 379 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETString) 380 if err != nil { 381 return nil, err 382 } 383 384 bf.tp.Flen = args[0].GetType().Flen 385 sig := &builtinDecodeSig{bf} 386 sig.setPbCode(fidelpb.ScalarFuncSig_Decode) 387 return sig, nil 388 } 389 390 type builtinDecodeSig struct { 391 baseBuiltinFunc 392 } 393 394 func (b *builtinDecodeSig) Clone() builtinFunc { 395 newSig := &builtinDecodeSig{} 396 newSig.cloneFrom(&b.baseBuiltinFunc) 397 return newSig 398 } 399 400 // evalString evals DECODE(str, password_str). 401 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_decode 402 func (b *builtinDecodeSig) evalString(event chunk.Event) (string, bool, error) { 403 dataStr, isNull, err := b.args[0].EvalString(b.ctx, event) 404 if isNull || err != nil { 405 return "", true, err 406 } 407 408 passwordStr, isNull, err := b.args[1].EvalString(b.ctx, event) 409 if isNull || err != nil { 410 return "", true, err 411 } 412 413 decodeStr, err := encrypt.ALLEGROSQLDecode(dataStr, passwordStr) 414 return decodeStr, false, err 415 } 416 417 type desDecryptFunctionClass struct { 418 baseFunctionClass 419 } 420 421 func (c *desDecryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 422 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_DECRYPT") 423 } 424 425 type desEncryptFunctionClass struct { 426 baseFunctionClass 427 } 428 429 func (c *desEncryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 430 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_ENCRYPT") 431 } 432 433 type encodeFunctionClass struct { 434 baseFunctionClass 435 } 436 437 func (c *encodeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 438 if err := c.verifyArgs(args); err != nil { 439 return nil, err 440 } 441 442 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETString) 443 if err != nil { 444 return nil, err 445 } 446 447 bf.tp.Flen = args[0].GetType().Flen 448 sig := &builtinEncodeSig{bf} 449 sig.setPbCode(fidelpb.ScalarFuncSig_Encode) 450 return sig, nil 451 } 452 453 type builtinEncodeSig struct { 454 baseBuiltinFunc 455 } 456 457 func (b *builtinEncodeSig) Clone() builtinFunc { 458 newSig := &builtinEncodeSig{} 459 newSig.cloneFrom(&b.baseBuiltinFunc) 460 return newSig 461 } 462 463 // evalString evals ENCODE(crypt_str, password_str). 464 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_encode 465 func (b *builtinEncodeSig) evalString(event chunk.Event) (string, bool, error) { 466 decodeStr, isNull, err := b.args[0].EvalString(b.ctx, event) 467 if isNull || err != nil { 468 return "", true, err 469 } 470 471 passwordStr, isNull, err := b.args[1].EvalString(b.ctx, event) 472 if isNull || err != nil { 473 return "", true, err 474 } 475 476 dataStr, err := encrypt.ALLEGROSQLEncode(decodeStr, passwordStr) 477 return dataStr, false, err 478 } 479 480 type encryptFunctionClass struct { 481 baseFunctionClass 482 } 483 484 func (c *encryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 485 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "ENCRYPT") 486 } 487 488 type oldPasswordFunctionClass struct { 489 baseFunctionClass 490 } 491 492 func (c *oldPasswordFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 493 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "OLD_PASSWORD") 494 } 495 496 type passwordFunctionClass struct { 497 baseFunctionClass 498 } 499 500 func (c *passwordFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 501 if err := c.verifyArgs(args); err != nil { 502 return nil, err 503 } 504 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) 505 if err != nil { 506 return nil, err 507 } 508 bf.tp.Flen = allegrosql.PWDHashLen + 1 509 sig := &builtinPasswordSig{bf} 510 sig.setPbCode(fidelpb.ScalarFuncSig_Password) 511 return sig, nil 512 } 513 514 type builtinPasswordSig struct { 515 baseBuiltinFunc 516 } 517 518 func (b *builtinPasswordSig) Clone() builtinFunc { 519 newSig := &builtinPasswordSig{} 520 newSig.cloneFrom(&b.baseBuiltinFunc) 521 return newSig 522 } 523 524 // evalString evals a builtinPasswordSig. 525 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password 526 func (b *builtinPasswordSig) evalString(event chunk.Event) (d string, isNull bool, err error) { 527 pass, isNull, err := b.args[0].EvalString(b.ctx, event) 528 if isNull || err != nil { 529 return "", err != nil, err 530 } 531 532 if len(pass) == 0 { 533 return "", false, nil 534 } 535 536 // We should append a warning here because function "PASSWORD" is deprecated since MyALLEGROSQL 5.7.6. 537 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password 538 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoRememristed.GenWithStackByArgs("PASSWORD")) 539 540 return auth.EncodePassword(pass), false, nil 541 } 542 543 type randomBytesFunctionClass struct { 544 baseFunctionClass 545 } 546 547 func (c *randomBytesFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 548 if err := c.verifyArgs(args); err != nil { 549 return nil, err 550 } 551 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETInt) 552 if err != nil { 553 return nil, err 554 } 555 bf.tp.Flen = 1024 // Max allowed random bytes 556 types.SetBinChsClnFlag(bf.tp) 557 sig := &builtinRandomBytesSig{bf} 558 return sig, nil 559 } 560 561 type builtinRandomBytesSig struct { 562 baseBuiltinFunc 563 } 564 565 func (b *builtinRandomBytesSig) Clone() builtinFunc { 566 newSig := &builtinRandomBytesSig{} 567 newSig.cloneFrom(&b.baseBuiltinFunc) 568 return newSig 569 } 570 571 // evalString evals RANDOM_BYTES(len). 572 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_random-bytes 573 func (b *builtinRandomBytesSig) evalString(event chunk.Event) (string, bool, error) { 574 len, isNull, err := b.args[0].EvalInt(b.ctx, event) 575 if isNull || err != nil { 576 return "", true, err 577 } 578 if len < 1 || len > 1024 { 579 return "", false, types.ErrOverflow.GenWithStackByArgs("length", "random_bytes") 580 } 581 buf := make([]byte, len) 582 if n, err := rand.Read(buf); err != nil { 583 return "", true, err 584 } else if int64(n) != len { 585 return "", false, errors.New("fail to generate random bytes") 586 } 587 return string(buf), false, nil 588 } 589 590 type md5FunctionClass struct { 591 baseFunctionClass 592 } 593 594 func (c *md5FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 595 if err := c.verifyArgs(args); err != nil { 596 return nil, err 597 } 598 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) 599 if err != nil { 600 return nil, err 601 } 602 bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo() 603 bf.tp.Flen = 32 604 sig := &builtinMD5Sig{bf} 605 sig.setPbCode(fidelpb.ScalarFuncSig_MD5) 606 return sig, nil 607 } 608 609 type builtinMD5Sig struct { 610 baseBuiltinFunc 611 } 612 613 func (b *builtinMD5Sig) Clone() builtinFunc { 614 newSig := &builtinMD5Sig{} 615 newSig.cloneFrom(&b.baseBuiltinFunc) 616 return newSig 617 } 618 619 // evalString evals a builtinMD5Sig. 620 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_md5 621 func (b *builtinMD5Sig) evalString(event chunk.Event) (string, bool, error) { 622 arg, isNull, err := b.args[0].EvalString(b.ctx, event) 623 if isNull || err != nil { 624 return "", isNull, err 625 } 626 sum := md5.Sum([]byte(arg)) 627 hexStr := fmt.Sprintf("%x", sum) 628 return hexStr, false, nil 629 } 630 631 type sha1FunctionClass struct { 632 baseFunctionClass 633 } 634 635 func (c *sha1FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 636 if err := c.verifyArgs(args); err != nil { 637 return nil, err 638 } 639 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) 640 if err != nil { 641 return nil, err 642 } 643 bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo() 644 bf.tp.Flen = 40 645 sig := &builtinSHA1Sig{bf} 646 sig.setPbCode(fidelpb.ScalarFuncSig_SHA1) 647 return sig, nil 648 } 649 650 type builtinSHA1Sig struct { 651 baseBuiltinFunc 652 } 653 654 func (b *builtinSHA1Sig) Clone() builtinFunc { 655 newSig := &builtinSHA1Sig{} 656 newSig.cloneFrom(&b.baseBuiltinFunc) 657 return newSig 658 } 659 660 // evalString evals SHA1(str). 661 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha1 662 // The value is returned as a string of 40 hexadecimal digits, or NULL if the argument was NULL. 663 func (b *builtinSHA1Sig) evalString(event chunk.Event) (string, bool, error) { 664 str, isNull, err := b.args[0].EvalString(b.ctx, event) 665 if isNull || err != nil { 666 return "", isNull, err 667 } 668 hasher := sha1.New() 669 _, err = hasher.Write([]byte(str)) 670 if err != nil { 671 return "", true, err 672 } 673 return fmt.Sprintf("%x", hasher.Sum(nil)), false, nil 674 } 675 676 type sha2FunctionClass struct { 677 baseFunctionClass 678 } 679 680 func (c *sha2FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 681 if err := c.verifyArgs(args); err != nil { 682 return nil, err 683 } 684 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETInt) 685 if err != nil { 686 return nil, err 687 } 688 bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo() 689 bf.tp.Flen = 128 // sha512 690 sig := &builtinSHA2Sig{bf} 691 sig.setPbCode(fidelpb.ScalarFuncSig_SHA2) 692 return sig, nil 693 } 694 695 type builtinSHA2Sig struct { 696 baseBuiltinFunc 697 } 698 699 func (b *builtinSHA2Sig) Clone() builtinFunc { 700 newSig := &builtinSHA2Sig{} 701 newSig.cloneFrom(&b.baseBuiltinFunc) 702 return newSig 703 } 704 705 // Supported hash length of SHA-2 family 706 const ( 707 SHA0 = 0 708 SHA224 = 224 709 SHA256 = 256 710 SHA384 = 384 711 SHA512 = 512 712 ) 713 714 // evalString evals SHA2(str, hash_length). 715 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha2 716 func (b *builtinSHA2Sig) evalString(event chunk.Event) (string, bool, error) { 717 str, isNull, err := b.args[0].EvalString(b.ctx, event) 718 if isNull || err != nil { 719 return "", isNull, err 720 } 721 hashLength, isNull, err := b.args[1].EvalInt(b.ctx, event) 722 if isNull || err != nil { 723 return "", isNull, err 724 } 725 var hasher hash.Hash 726 switch int(hashLength) { 727 case SHA0, SHA256: 728 hasher = sha256.New() 729 case SHA224: 730 hasher = sha256.New224() 731 case SHA384: 732 hasher = sha512.New384() 733 case SHA512: 734 hasher = sha512.New() 735 } 736 if hasher == nil { 737 return "", true, nil 738 } 739 740 _, err = hasher.Write([]byte(str)) 741 if err != nil { 742 return "", true, err 743 } 744 return fmt.Sprintf("%x", hasher.Sum(nil)), false, nil 745 } 746 747 // deflate compresses a string using the DEFLATE format. 748 func deflate(data []byte) ([]byte, error) { 749 var buffer bytes.Buffer 750 w := zlib.NewWriter(&buffer) 751 if _, err := w.Write(data); err != nil { 752 return nil, err 753 } 754 if err := w.Close(); err != nil { 755 return nil, err 756 } 757 return buffer.Bytes(), nil 758 } 759 760 // inflate uncompresses a string using the DEFLATE format. 761 func inflate(compressStr []byte) ([]byte, error) { 762 reader := bytes.NewReader(compressStr) 763 var out bytes.Buffer 764 r, err := zlib.NewReader(reader) 765 if err != nil { 766 return nil, err 767 } 768 if _, err = io.Copy(&out, r); err != nil { 769 return nil, err 770 } 771 err = r.Close() 772 return out.Bytes(), err 773 } 774 775 type compressFunctionClass struct { 776 baseFunctionClass 777 } 778 779 func (c *compressFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 780 if err := c.verifyArgs(args); err != nil { 781 return nil, err 782 } 783 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) 784 if err != nil { 785 return nil, err 786 } 787 srcLen := args[0].GetType().Flen 788 compressBound := srcLen + (srcLen >> 12) + (srcLen >> 14) + (srcLen >> 25) + 13 789 if compressBound > allegrosql.MaxBlobWidth { 790 compressBound = allegrosql.MaxBlobWidth 791 } 792 bf.tp.Flen = compressBound 793 types.SetBinChsClnFlag(bf.tp) 794 sig := &builtinCompressSig{bf} 795 sig.setPbCode(fidelpb.ScalarFuncSig_Compress) 796 return sig, nil 797 } 798 799 type builtinCompressSig struct { 800 baseBuiltinFunc 801 } 802 803 func (b *builtinCompressSig) Clone() builtinFunc { 804 newSig := &builtinCompressSig{} 805 newSig.cloneFrom(&b.baseBuiltinFunc) 806 return newSig 807 } 808 809 // evalString evals COMPRESS(str). 810 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_compress 811 func (b *builtinCompressSig) evalString(event chunk.Event) (string, bool, error) { 812 str, isNull, err := b.args[0].EvalString(b.ctx, event) 813 if isNull || err != nil { 814 return "", true, err 815 } 816 817 // According to doc: Empty strings are stored as empty strings. 818 if len(str) == 0 { 819 return "", false, nil 820 } 821 822 compressed, err := deflate([]byte(str)) 823 if err != nil { 824 return "", true, nil 825 } 826 827 resultLength := 4 + len(compressed) 828 829 // append "." if ends with space 830 shouldAppendSuffix := compressed[len(compressed)-1] == 32 831 if shouldAppendSuffix { 832 resultLength++ 833 } 834 835 buffer := make([]byte, resultLength) 836 binary.LittleEndian.PutUint32(buffer, uint32(len(str))) 837 copy(buffer[4:], compressed) 838 839 if shouldAppendSuffix { 840 buffer[len(buffer)-1] = '.' 841 } 842 843 return string(buffer), false, nil 844 } 845 846 type uncompressFunctionClass struct { 847 baseFunctionClass 848 } 849 850 func (c *uncompressFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 851 if err := c.verifyArgs(args); err != nil { 852 return nil, err 853 } 854 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) 855 if err != nil { 856 return nil, err 857 } 858 bf.tp.Flen = allegrosql.MaxBlobWidth 859 types.SetBinChsClnFlag(bf.tp) 860 sig := &builtinUncompressSig{bf} 861 sig.setPbCode(fidelpb.ScalarFuncSig_Uncompress) 862 return sig, nil 863 } 864 865 type builtinUncompressSig struct { 866 baseBuiltinFunc 867 } 868 869 func (b *builtinUncompressSig) Clone() builtinFunc { 870 newSig := &builtinUncompressSig{} 871 newSig.cloneFrom(&b.baseBuiltinFunc) 872 return newSig 873 } 874 875 // evalString evals UNCOMPRESS(compressed_string). 876 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompress 877 func (b *builtinUncompressSig) evalString(event chunk.Event) (string, bool, error) { 878 sc := b.ctx.GetStochastikVars().StmtCtx 879 payload, isNull, err := b.args[0].EvalString(b.ctx, event) 880 if isNull || err != nil { 881 return "", true, err 882 } 883 if len(payload) == 0 { 884 return "", false, nil 885 } 886 if len(payload) <= 4 { 887 // corrupted 888 sc.AppendWarning(errZlibZData) 889 return "", true, nil 890 } 891 length := binary.LittleEndian.Uint32([]byte(payload[0:4])) 892 bytes, err := inflate([]byte(payload[4:])) 893 if err != nil { 894 sc.AppendWarning(errZlibZData) 895 return "", true, nil 896 } 897 if length < uint32(len(bytes)) { 898 sc.AppendWarning(errZlibZBuf) 899 return "", true, nil 900 } 901 return string(bytes), false, nil 902 } 903 904 type uncompressedLengthFunctionClass struct { 905 baseFunctionClass 906 } 907 908 func (c *uncompressedLengthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 909 if err := c.verifyArgs(args); err != nil { 910 return nil, err 911 } 912 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString) 913 if err != nil { 914 return nil, err 915 } 916 bf.tp.Flen = 10 917 sig := &builtinUncompressedLengthSig{bf} 918 sig.setPbCode(fidelpb.ScalarFuncSig_UncompressedLength) 919 return sig, nil 920 } 921 922 type builtinUncompressedLengthSig struct { 923 baseBuiltinFunc 924 } 925 926 func (b *builtinUncompressedLengthSig) Clone() builtinFunc { 927 newSig := &builtinUncompressedLengthSig{} 928 newSig.cloneFrom(&b.baseBuiltinFunc) 929 return newSig 930 } 931 932 // evalInt evals UNCOMPRESSED_LENGTH(str). 933 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompressed-length 934 func (b *builtinUncompressedLengthSig) evalInt(event chunk.Event) (int64, bool, error) { 935 sc := b.ctx.GetStochastikVars().StmtCtx 936 payload, isNull, err := b.args[0].EvalString(b.ctx, event) 937 if isNull || err != nil { 938 return 0, true, err 939 } 940 if len(payload) == 0 { 941 return 0, false, nil 942 } 943 if len(payload) <= 4 { 944 // corrupted 945 sc.AppendWarning(errZlibZData) 946 return 0, false, nil 947 } 948 len := binary.LittleEndian.Uint32([]byte(payload)[0:4]) 949 return int64(len), false, nil 950 } 951 952 type validatePasswordStrengthFunctionClass struct { 953 baseFunctionClass 954 } 955 956 func (c *validatePasswordStrengthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 957 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "VALIDATE_PASSWORD_STRENGTH") 958 }