Hex Artifact Content

Artifact c51db5e24aacfd68cdbd89edad5c3214913e579e74edd3672697611485b5e257:


0000: 2f 2a 0a 20 2a 20 44 69 67 65 73 74 20 43 6f 6d  /*. * Digest Com
0010: 6d 61 6e 64 20 61 6e 64 20 53 74 61 63 6b 65 64  mand and Stacked
0020: 20 54 72 61 6e 73 66 6f 72 6d 20 43 68 61 6e 6e   Transform Chann
0030: 65 6c 0a 20 2a 0a 20 2a 20 43 6f 70 79 72 69 67  el. *. * Copyrig
0040: 68 74 20 28 43 29 20 32 30 32 33 20 42 72 69 61  ht (C) 2023 Bria
0050: 6e 20 4f 27 48 61 67 61 6e 0a 20 2a 0a 20 2a 2f  n O'Hagan. *. */
0060: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 74 6c 73 49  ..#include "tlsI
0070: 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22  nt.h".#include "
0080: 74 63 6c 4f 70 74 73 2e 68 22 0a 23 69 6e 63 6c  tclOpts.h".#incl
0090: 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 23 69 6e 63  ude <tcl.h>.#inc
00a0: 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23  lude <stdio.h>.#
00b0: 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e  include <string.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6f 70 65  h>.#include <ope
00d0: 6e 73 73 6c 2f 65 76 70 2e 68 3e 0a 0a 2f 2a 20  nssl/evp.h>../* 
00e0: 43 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 63 6f 6e  Constants */.con
00f0: 73 74 20 63 68 61 72 20 2a 68 65 78 20 3d 20 22  st char *hex = "
0100: 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46  0123456789ABCDEF
0110: 22 3b 0a 23 64 65 66 69 6e 65 20 52 45 41 53 4f  ";.#define REASO
0120: 4e 28 29 09 45 52 52 5f 72 65 61 73 6f 6e 5f 65  N().ERR_reason_e
0130: 72 72 6f 72 5f 73 74 72 69 6e 67 28 45 52 52 5f  rror_string(ERR_
0140: 67 65 74 5f 65 72 72 6f 72 28 29 29 0a 23 64 65  get_error()).#de
0150: 66 69 6e 65 20 42 55 46 46 45 52 5f 53 49 5a 45  fine BUFFER_SIZE
0160: 20 36 35 35 33 36 0a 23 64 65 66 69 6e 65 20 42   65536.#define B
0170: 49 4e 5f 46 4f 52 4d 41 54 20 30 0a 23 64 65 66  IN_FORMAT 0.#def
0180: 69 6e 65 20 48 45 58 5f 46 4f 52 4d 41 54 20 31  ine HEX_FORMAT 1
0190: 0a 0a 2f 2a 0a 20 2a 20 54 68 69 73 20 73 74 72  ../*. * This str
01a0: 75 63 74 75 72 65 20 64 65 73 63 72 69 62 65 73  ucture describes
01b0: 20 74 68 65 20 70 65 72 2d 69 6e 73 74 61 6e 63   the per-instanc
01c0: 65 20 73 74 61 74 65 20 6f 66 20 61 6e 20 53 53  e state of an SS
01d0: 4c 20 63 68 61 6e 6e 65 6c 2e 0a 20 2a 0a 20 2a  L channel.. *. *
01e0: 20 54 68 65 20 53 53 4c 20 70 72 6f 63 65 73 73   The SSL process
01f0: 69 6e 67 20 63 6f 6e 74 65 78 74 20 69 73 20 6d  ing context is m
0200: 61 69 6e 74 61 69 6e 65 64 20 68 65 72 65 2c 20  aintained here, 
0210: 69 6e 20 74 68 65 20 43 6c 69 65 6e 74 44 61 74  in the ClientDat
0220: 61 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  a. */.typedef st
0230: 72 75 63 74 20 44 69 67 65 73 74 53 74 61 74 65  ruct DigestState
0240: 20 7b 0a 09 54 63 6c 5f 43 68 61 6e 6e 65 6c 20   {..Tcl_Channel 
0250: 73 65 6c 66 3b 09 2f 2a 20 54 68 69 73 20 73 6f  self;./* This so
0260: 63 6b 65 74 20 63 68 61 6e 6e 65 6c 20 2a 2f 0a  cket channel */.
0270: 09 54 63 6c 5f 54 69 6d 65 72 54 6f 6b 65 6e 20  .Tcl_TimerToken 
0280: 74 69 6d 65 72 3b 09 2f 2a 20 54 69 6d 65 72 20  timer;./* Timer 
0290: 66 6f 72 20 72 65 61 64 20 65 76 65 6e 74 73 20  for read events 
02a0: 2a 2f 0a 0a 09 69 6e 74 20 66 6c 61 67 73 3b 09  */...int flags;.
02b0: 09 2f 2a 20 43 68 61 6e 20 63 6f 6e 66 69 67 20  ./* Chan config 
02c0: 66 6c 61 67 73 20 2a 2f 0a 09 69 6e 74 20 77 61  flags */..int wa
02d0: 74 63 68 4d 61 73 6b 3b 09 09 2f 2a 20 43 75 72  tchMask;../* Cur
02e0: 72 65 6e 74 20 57 61 74 63 68 50 72 6f 63 20 6d  rent WatchProc m
02f0: 61 73 6b 20 2a 2f 0a 09 69 6e 74 20 6d 6f 64 65  ask */..int mode
0300: 3b 09 09 2f 2a 20 43 75 72 72 65 6e 74 20 6d 6f  ;../* Current mo
0310: 64 65 20 6f 66 20 70 61 72 65 6e 74 20 63 68 61  de of parent cha
0320: 6e 6e 65 6c 20 2a 2f 0a 09 69 6e 74 20 66 6f 72  nnel */..int for
0330: 6d 61 74 3b 09 09 2f 2a 20 4f 75 74 70 75 74 20  mat;../* Output 
0340: 66 6f 72 6d 61 74 20 2a 2f 0a 0a 09 54 63 6c 5f  format */...Tcl_
0350: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 09  Interp *interp;.
0360: 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 74 65 72  /* Current inter
0370: 70 72 65 74 65 72 20 2a 2f 0a 09 45 56 50 5f 4d  preter */..EVP_M
0380: 44 5f 43 54 58 20 2a 63 74 78 3b 09 2f 2a 20 4d  D_CTX *ctx;./* M
0390: 44 20 43 6f 6e 74 65 78 74 20 2a 2f 0a 7d 20 44  D Context */.} D
03a0: 69 67 65 73 74 53 74 61 74 65 3b 0a 0a 2f 2a 2a  igestState;../**
03b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03f0: 2a 2f 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d  */../*. *-------
0400: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0410: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0420: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0430: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a  ------------. *.
0440: 20 2a 20 44 69 67 65 73 74 46 69 6c 65 20 2d 2d   * DigestFile --
0450: 0a 20 2a 0a 20 2a 09 52 65 74 75 72 6e 20 6d 65  . *. *.Return me
0460: 73 73 61 67 65 20 64 69 67 65 73 74 20 66 6f 72  ssage digest for
0470: 20 66 69 6c 65 20 75 73 69 6e 67 20 75 73 65 72   file using user
0480: 20 73 70 65 63 69 66 69 65 64 20 68 61 73 68 20   specified hash 
0490: 66 75 6e 63 74 69 6f 6e 2e 0a 20 2a 0a 20 2a 20  function.. *. * 
04a0: 52 65 74 75 72 6e 73 3a 0a 20 2a 09 54 43 4c 5f  Returns:. *.TCL_
04b0: 4f 4b 20 6f 72 20 54 43 4c 5f 45 52 52 4f 52 0a  OK or TCL_ERROR.
04c0: 20 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63   *. * Side effec
04d0: 74 73 3a 0a 20 2a 09 52 65 73 75 6c 74 20 69 73  ts:. *.Result is
04e0: 20 6d 65 73 73 61 67 65 20 64 69 67 65 73 74 20   message digest 
04f0: 6f 72 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  or error message
0500: 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  . *. *----------
0510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0530: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0540: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 69 6e  ---------. */.in
0550: 74 20 44 69 67 65 73 74 46 69 6c 65 28 54 63 6c  t DigestFile(Tcl
0560: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
0570: 20 54 63 6c 5f 4f 62 6a 20 2a 66 69 6c 65 6e 61   Tcl_Obj *filena
0580: 6d 65 2c 20 63 6f 6e 73 74 20 45 56 50 5f 4d 44  me, const EVP_MD
0590: 20 2a 6d 64 2c 20 69 6e 74 20 66 6f 72 6d 61 74   *md, int format
05a0: 2c 0a 09 54 63 6c 5f 4f 62 6a 20 2a 6b 65 79 4f  ,..Tcl_Obj *keyO
05b0: 62 6a 29 20 7b 0a 20 20 20 20 45 56 50 5f 4d 44  bj) {.    EVP_MD
05c0: 5f 43 54 58 20 2a 63 74 78 20 3d 20 28 45 56 50  _CTX *ctx = (EVP
05d0: 5f 4d 44 5f 43 54 58 20 2a 29 20 4e 55 4c 4c 3b  _MD_CTX *) NULL;
05e0: 0a 20 20 20 20 48 4d 41 43 5f 43 54 58 20 2a 68  .    HMAC_CTX *h
05f0: 63 74 78 20 3d 20 28 48 4d 41 43 5f 43 54 58 20  ctx = (HMAC_CTX 
0600: 2a 29 20 4e 55 4c 4c 3b 0a 20 20 20 20 54 63 6c  *) NULL;.    Tcl
0610: 5f 43 68 61 6e 6e 65 6c 20 63 68 61 6e 3b 0a 20  _Channel chan;. 
0620: 20 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72     unsigned char
0630: 20 62 75 66 5b 42 55 46 46 45 52 5f 53 49 5a 45   buf[BUFFER_SIZE
0640: 5d 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20  ];.    unsigned 
0650: 63 68 61 72 20 6d 64 5f 62 75 66 5b 45 56 50 5f  char md_buf[EVP_
0660: 4d 41 58 5f 4d 44 5f 53 49 5a 45 5d 3b 0a 20 20  MAX_MD_SIZE];.  
0670: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d    unsigned int m
0680: 64 5f 6c 65 6e 3b 0a 20 20 20 20 75 6e 73 69 67  d_len;.    unsig
0690: 6e 65 64 20 63 68 61 72 20 2a 6b 65 79 3b 0a 20  ned char *key;. 
06a0: 20 20 20 69 6e 74 20 6b 65 79 5f 6c 65 6e 2c 20     int key_len, 
06b0: 72 65 73 3b 0a 0a 20 20 20 20 2f 2a 20 4f 70 65  res;..    /* Ope
06c0: 6e 20 66 69 6c 65 20 63 68 61 6e 6e 65 6c 20 2a  n file channel *
06d0: 2f 0a 20 20 20 20 63 68 61 6e 20 3d 20 54 63 6c  /.    chan = Tcl
06e0: 5f 46 53 4f 70 65 6e 46 69 6c 65 43 68 61 6e 6e  _FSOpenFileChann
06f0: 65 6c 28 69 6e 74 65 72 70 2c 20 66 69 6c 65 6e  el(interp, filen
0700: 61 6d 65 2c 20 22 72 62 22 2c 20 30 34 34 34 29  ame, "rb", 0444)
0710: 3b 0a 20 20 20 20 69 66 20 28 63 68 61 6e 20 3d  ;.    if (chan =
0720: 3d 20 28 54 63 6c 5f 43 68 61 6e 6e 65 6c 29 20  = (Tcl_Channel) 
0730: 4e 55 4c 4c 29 20 7b 0a 09 72 65 74 75 72 6e 20  NULL) {..return 
0740: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  TCL_ERROR;.    }
0750: 0a 0a 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75  ..    /* Configu
0760: 72 65 20 63 68 61 6e 6e 65 6c 20 2a 2f 0a 20 20  re channel */.  
0770: 20 20 69 66 20 28 54 63 6c 5f 53 65 74 43 68 61    if (Tcl_SetCha
0780: 6e 6e 65 6c 4f 70 74 69 6f 6e 28 69 6e 74 65 72  nnelOption(inter
0790: 70 2c 20 63 68 61 6e 2c 20 22 2d 74 72 61 6e 73  p, chan, "-trans
07a0: 6c 61 74 69 6f 6e 22 2c 20 22 62 69 6e 61 72 79  lation", "binary
07b0: 22 29 20 3d 3d 20 54 43 4c 5f 45 52 52 4f 52 29  ") == TCL_ERROR)
07c0: 20 7b 0a 09 67 6f 74 6f 20 65 72 72 6f 72 3b 0a   {..goto error;.
07d0: 20 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 53 65      }.    Tcl_Se
07e0: 74 43 68 61 6e 6e 65 6c 42 75 66 66 65 72 53 69  tChannelBufferSi
07f0: 7a 65 28 63 68 61 6e 2c 20 42 55 46 46 45 52 5f  ze(chan, BUFFER_
0800: 53 49 5a 45 29 3b 0a 0a 20 20 20 20 2f 2a 20 43  SIZE);..    /* C
0810: 72 65 61 74 65 20 6d 65 73 73 61 67 65 20 64 69  reate message di
0820: 67 65 73 74 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  gest context */.
0830: 20 20 20 20 69 66 20 28 6b 65 79 4f 62 6a 20 3d      if (keyObj =
0840: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 63 74 78 20 3d  = NULL) {..ctx =
0850: 20 45 56 50 5f 4d 44 5f 43 54 58 5f 6e 65 77 28   EVP_MD_CTX_new(
0860: 29 3b 0a 09 72 65 73 20 3d 20 28 63 74 78 20 21  );..res = (ctx !
0870: 3d 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 7d 20 65  = NULL);.    } e
0880: 6c 73 65 20 7b 0a 09 68 63 74 78 20 3d 20 48 4d  lse {..hctx = HM
0890: 41 43 5f 43 54 58 5f 6e 65 77 28 29 3b 0a 09 72  AC_CTX_new();..r
08a0: 65 73 20 3d 20 28 68 63 74 78 20 21 3d 20 4e 55  es = (hctx != NU
08b0: 4c 4c 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  LL);.    }.    i
08c0: 66 20 28 21 72 65 73 29 20 7b 0a 09 54 63 6c 5f  f (!res) {..Tcl_
08d0: 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74  AppendResult(int
08e0: 65 72 70 2c 20 22 43 72 65 61 74 65 20 64 69 67  erp, "Create dig
08f0: 65 73 74 20 63 6f 6e 74 65 78 74 20 66 61 69 6c  est context fail
0900: 65 64 3a 20 22 2c 20 52 45 41 53 4f 4e 28 29 2c  ed: ", REASON(),
0910: 20 4e 55 4c 4c 29 3b 0a 09 67 6f 74 6f 20 65 72   NULL);..goto er
0920: 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  ror;.    }..    
0930: 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 68 61  /* Initialize ha
0940: 73 68 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  sh function */. 
0950: 20 20 20 69 66 20 28 6b 65 79 4f 62 6a 20 3d 3d     if (keyObj ==
0960: 20 4e 55 4c 4c 29 20 7b 0a 09 72 65 73 20 3d 20   NULL) {..res = 
0970: 45 56 50 5f 44 69 67 65 73 74 49 6e 69 74 5f 65  EVP_DigestInit_e
0980: 78 28 63 74 78 2c 20 6d 64 2c 20 4e 55 4c 4c 29  x(ctx, md, NULL)
0990: 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09  ;.    } else {..
09a0: 6b 65 79 20 3d 20 54 63 6c 5f 47 65 74 42 79 74  key = Tcl_GetByt
09b0: 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6b 65  eArrayFromObj(ke
09c0: 79 4f 62 6a 2c 20 26 6b 65 79 5f 6c 65 6e 29 3b  yObj, &key_len);
09d0: 0a 09 72 65 73 20 3d 20 48 4d 41 43 5f 49 6e 69  ..res = HMAC_Ini
09e0: 74 5f 65 78 28 68 63 74 78 2c 20 28 63 6f 6e 73  t_ex(hctx, (cons
09f0: 74 20 76 6f 69 64 20 2a 29 20 6b 65 79 2c 20 6b  t void *) key, k
0a00: 65 79 5f 6c 65 6e 2c 20 6d 64 2c 20 4e 55 4c 4c  ey_len, md, NULL
0a10: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20  );.    }.    if 
0a20: 28 21 72 65 73 29 20 7b 0a 09 54 63 6c 5f 41 70  (!res) {..Tcl_Ap
0a30: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
0a40: 70 2c 20 22 49 6e 69 74 69 61 6c 69 7a 65 20 64  p, "Initialize d
0a50: 69 67 65 73 74 20 66 61 69 6c 65 64 3a 20 22 2c  igest failed: ",
0a60: 20 52 45 41 53 4f 4e 28 29 2c 20 4e 55 4c 4c 29   REASON(), NULL)
0a70: 3b 0a 09 67 6f 74 6f 20 65 72 72 6f 72 3b 0a 20  ;..goto error;. 
0a80: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 52 65 61     }..    /* Rea
0a90: 64 20 66 69 6c 65 20 64 61 74 61 20 61 6e 64 20  d file data and 
0aa0: 75 70 64 61 74 65 20 68 61 73 68 20 66 75 6e 63  update hash func
0ab0: 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 77 68 69 6c  tion */.    whil
0ac0: 65 20 28 21 54 63 6c 5f 45 6f 66 28 63 68 61 6e  e (!Tcl_Eof(chan
0ad0: 29 29 20 7b 0a 09 69 6e 74 20 6c 65 6e 20 3d 20  )) {..int len = 
0ae0: 54 63 6c 5f 52 65 61 64 52 61 77 28 63 68 61 6e  Tcl_ReadRaw(chan
0af0: 2c 20 28 63 68 61 72 20 2a 29 20 62 75 66 2c 20  , (char *) buf, 
0b00: 42 55 46 46 45 52 5f 53 49 5a 45 29 3b 0a 09 69  BUFFER_SIZE);..i
0b10: 66 20 28 6b 65 79 4f 62 6a 20 3d 3d 20 4e 55 4c  f (keyObj == NUL
0b20: 4c 29 20 7b 0a 09 20 20 20 20 72 65 73 20 3d 20  L) {..    res = 
0b30: 45 56 50 5f 44 69 67 65 73 74 55 70 64 61 74 65  EVP_DigestUpdate
0b40: 28 63 74 78 2c 20 26 62 75 66 2c 20 28 73 69 7a  (ctx, &buf, (siz
0b50: 65 5f 74 29 20 6c 65 6e 29 3b 0a 09 7d 20 65 6c  e_t) len);..} el
0b60: 73 65 20 7b 0a 09 20 20 20 20 72 65 73 20 3d 20  se {..    res = 
0b70: 48 4d 41 43 5f 55 70 64 61 74 65 28 68 63 74 78  HMAC_Update(hctx
0b80: 2c 20 26 62 75 66 5b 30 5d 2c 20 28 73 69 7a 65  , &buf[0], (size
0b90: 5f 74 29 20 6c 65 6e 29 3b 0a 09 7d 0a 09 69 66  _t) len);..}..if
0ba0: 20 28 6c 65 6e 20 3e 20 30 20 26 26 20 21 72 65   (len > 0 && !re
0bb0: 73 29 20 7b 0a 09 20 20 20 20 54 63 6c 5f 41 70  s) {..    Tcl_Ap
0bc0: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
0bd0: 70 2c 20 22 55 70 64 61 74 65 20 64 69 67 65 73  p, "Update diges
0be0: 74 20 66 61 69 6c 65 64 3a 20 22 2c 20 52 45 41  t failed: ", REA
0bf0: 53 4f 4e 28 29 2c 20 4e 55 4c 4c 29 3b 0a 09 20  SON(), NULL);.. 
0c00: 20 20 20 67 6f 74 6f 20 65 72 72 6f 72 3b 0a 09     goto error;..
0c10: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  }.    }..    /* 
0c20: 43 6c 6f 73 65 20 63 68 61 6e 6e 65 6c 20 2a 2f  Close channel */
0c30: 0a 20 20 20 20 69 66 20 28 54 63 6c 5f 43 6c 6f  .    if (Tcl_Clo
0c40: 73 65 28 69 6e 74 65 72 70 2c 20 63 68 61 6e 29  se(interp, chan)
0c50: 20 3d 3d 20 54 43 4c 5f 45 52 52 4f 52 29 20 7b   == TCL_ERROR) {
0c60: 0a 09 63 68 61 6e 20 3d 20 28 54 63 6c 5f 43 68  ..chan = (Tcl_Ch
0c70: 61 6e 6e 65 6c 29 20 4e 55 4c 4c 3b 0a 09 67 6f  annel) NULL;..go
0c80: 74 6f 20 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a  to error;.    }.
0c90: 20 20 20 20 63 68 61 6e 20 3d 20 28 54 63 6c 5f      chan = (Tcl_
0ca0: 43 68 61 6e 6e 65 6c 29 20 4e 55 4c 4c 3b 0a 0a  Channel) NULL;..
0cb0: 20 20 20 20 2f 2a 20 46 69 6e 61 6c 69 7a 65 20      /* Finalize 
0cc0: 68 61 73 68 20 66 75 6e 63 74 69 6f 6e 20 61 6e  hash function an
0cd0: 64 20 63 61 6c 63 75 6c 61 74 65 20 6d 65 73 73  d calculate mess
0ce0: 61 67 65 20 64 69 67 65 73 74 20 2a 2f 0a 20 20  age digest */.  
0cf0: 20 20 69 66 20 28 6b 65 79 4f 62 6a 20 3d 3d 20    if (keyObj == 
0d00: 4e 55 4c 4c 29 20 7b 0a 09 72 65 73 20 3d 20 45  NULL) {..res = E
0d10: 56 50 5f 44 69 67 65 73 74 46 69 6e 61 6c 5f 65  VP_DigestFinal_e
0d20: 78 28 63 74 78 2c 20 6d 64 5f 62 75 66 2c 20 26  x(ctx, md_buf, &
0d30: 6d 64 5f 6c 65 6e 29 3b 0a 20 20 20 20 7d 20 65  md_len);.    } e
0d40: 6c 73 65 20 7b 0a 09 72 65 73 20 3d 20 48 4d 41  lse {..res = HMA
0d50: 43 5f 46 69 6e 61 6c 28 68 63 74 78 2c 20 6d 64  C_Final(hctx, md
0d60: 5f 62 75 66 2c 20 26 6d 64 5f 6c 65 6e 29 3b 0a  _buf, &md_len);.
0d70: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 28 21 72      }.    if (!r
0d80: 65 73 29 20 7b 0a 09 54 63 6c 5f 41 70 70 65 6e  es) {..Tcl_Appen
0d90: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
0da0: 22 46 69 6e 61 6c 69 7a 65 20 64 69 67 65 73 74  "Finalize digest
0db0: 20 66 61 69 6c 65 64 3a 20 22 2c 20 52 45 41 53   failed: ", REAS
0dc0: 4f 4e 28 29 2c 20 4e 55 4c 4c 29 3b 0a 09 67 6f  ON(), NULL);..go
0dd0: 74 6f 20 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a  to error;.    }.
0de0: 0a 20 20 20 20 2f 2a 20 44 6f 6e 65 20 77 69 74  .    /* Done wit
0df0: 68 20 73 74 72 75 63 74 20 2a 2f 0a 20 20 20 20  h struct */.    
0e00: 45 56 50 5f 4d 44 5f 43 54 58 5f 66 72 65 65 28  EVP_MD_CTX_free(
0e10: 63 74 78 29 3b 0a 20 20 20 20 63 74 78 20 3d 20  ctx);.    ctx = 
0e20: 4e 55 4c 4c 3b 0a 0a 20 20 20 20 2f 2a 20 52 65  NULL;..    /* Re
0e30: 74 75 72 6e 20 6d 65 73 73 61 67 65 20 64 69 67  turn message dig
0e40: 65 73 74 20 61 73 20 65 69 74 68 65 72 20 61 20  est as either a 
0e50: 62 69 6e 61 72 79 20 6f 72 20 68 65 78 20 73 74  binary or hex st
0e60: 72 69 6e 67 20 2a 2f 0a 20 20 20 20 69 66 20 28  ring */.    if (
0e70: 66 6f 72 6d 61 74 20 3d 3d 20 42 49 4e 5f 46 4f  format == BIN_FO
0e80: 52 4d 41 54 29 20 7b 0a 09 54 63 6c 5f 53 65 74  RMAT) {..Tcl_Set
0e90: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
0ea0: 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72  , Tcl_NewByteArr
0eb0: 61 79 4f 62 6a 28 6d 64 5f 62 75 66 2c 20 6d 64  ayObj(md_buf, md
0ec0: 5f 6c 65 6e 29 29 3b 0a 0a 20 20 20 20 7d 20 65  _len));..    } e
0ed0: 6c 73 65 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a  lse {..Tcl_Obj *
0ee0: 72 65 73 75 6c 74 4f 62 6a 20 3d 20 54 63 6c 5f  resultObj = Tcl_
0ef0: 4e 65 77 4f 62 6a 28 29 3b 0a 09 75 6e 73 69 67  NewObj();..unsig
0f00: 6e 65 64 20 63 68 61 72 20 2a 70 74 72 20 3d 20  ned char *ptr = 
0f10: 54 63 6c 5f 53 65 74 42 79 74 65 41 72 72 61 79  Tcl_SetByteArray
0f20: 4c 65 6e 67 74 68 28 72 65 73 75 6c 74 4f 62 6a  Length(resultObj
0f30: 2c 20 6d 64 5f 6c 65 6e 2a 32 29 3b 0a 0a 09 66  , md_len*2);...f
0f40: 6f 72 20 28 75 6e 73 69 67 6e 65 64 20 69 6e 74  or (unsigned int
0f50: 20 69 20 3d 20 30 3b 20 69 20 3c 20 6d 64 5f 6c   i = 0; i < md_l
0f60: 65 6e 3b 20 69 2b 2b 29 20 7b 0a 09 20 20 20 20  en; i++) {..    
0f70: 2a 70 74 72 2b 2b 20 3d 20 68 65 78 5b 28 6d 64  *ptr++ = hex[(md
0f80: 5f 62 75 66 5b 69 5d 20 3e 3e 20 34 29 20 26 20  _buf[i] >> 4) & 
0f90: 30 78 30 46 5d 3b 0a 09 20 20 20 20 2a 70 74 72  0x0F];..    *ptr
0fa0: 2b 2b 20 3d 20 68 65 78 5b 6d 64 5f 62 75 66 5b  ++ = hex[md_buf[
0fb0: 69 5d 20 26 20 30 78 30 46 5d 3b 0a 09 7d 0a 09  i] & 0x0F];..}..
0fc0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
0fd0: 28 69 6e 74 65 72 70 2c 20 72 65 73 75 6c 74 4f  (interp, resultO
0fe0: 62 6a 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  bj);.    }.    r
0ff0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 0a 65  eturn TCL_OK;..e
1000: 72 72 6f 72 3a 0a 20 20 20 20 69 66 20 28 63 68  rror:.    if (ch
1010: 61 6e 20 21 3d 20 28 54 63 6c 5f 43 68 61 6e 6e  an != (Tcl_Chann
1020: 65 6c 29 20 4e 55 4c 4c 29 20 7b 0a 09 54 63 6c  el) NULL) {..Tcl
1030: 5f 43 6c 6f 73 65 28 69 6e 74 65 72 70 2c 20 63  _Close(interp, c
1040: 68 61 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  han);.    }.    
1050: 69 66 20 28 63 74 78 20 21 3d 20 28 45 56 50 5f  if (ctx != (EVP_
1060: 4d 44 5f 43 54 58 20 2a 29 20 4e 55 4c 4c 29 20  MD_CTX *) NULL) 
1070: 7b 0a 09 45 56 50 5f 4d 44 5f 43 54 58 5f 66 72  {..EVP_MD_CTX_fr
1080: 65 65 28 63 74 78 29 3b 0a 20 20 20 20 7d 0a 20  ee(ctx);.    }. 
1090: 20 20 20 69 66 20 28 68 63 74 78 20 21 3d 20 28     if (hctx != (
10a0: 48 4d 41 43 5f 43 54 58 20 2a 29 20 4e 55 4c 4c  HMAC_CTX *) NULL
10b0: 29 20 7b 0a 09 48 4d 41 43 5f 43 54 58 5f 66 72  ) {..HMAC_CTX_fr
10c0: 65 65 28 68 63 74 78 29 3b 0a 20 20 20 20 7d 0a  ee(hctx);.    }.
10d0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
10e0: 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  RROR;.}../******
10f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1110: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
1130: 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  /*. *-----------
1140: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1150: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1160: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1170: 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44  --------. *. * D
1180: 69 67 65 73 74 42 6c 6f 63 6b 4d 6f 64 65 50 72  igestBlockModePr
1190: 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09 54 68 69 73  oc --. *. *.This
11a0: 20 70 72 6f 63 65 64 75 72 65 20 69 73 20 69 6e   procedure is in
11b0: 76 6f 6b 65 64 20 62 79 20 74 68 65 20 67 65 6e  voked by the gen
11c0: 65 72 69 63 20 49 4f 20 6c 65 76 65 6c 0a 20 2a  eric IO level. *
11d0: 20 20 20 20 20 20 20 74 6f 20 73 65 74 20 62 6c         to set bl
11e0: 6f 63 6b 69 6e 67 20 61 6e 64 20 6e 6f 6e 62 6c  ocking and nonbl
11f0: 6f 63 6b 69 6e 67 20 6d 6f 64 65 73 2e 0a 20 2a  ocking modes.. *
1200: 0a 20 2a 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09  . * Returns:. *.
1210: 30 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 20  0 if successful 
1220: 6f 72 20 50 4f 53 49 58 20 65 72 72 6f 72 20 63  or POSIX error c
1230: 6f 64 65 20 69 66 20 66 61 69 6c 65 64 2e 0a 20  ode if failed.. 
1240: 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74  *. * Side effect
1250: 73 3a 0a 20 2a 09 53 65 74 73 20 74 68 65 20 64  s:. *.Sets the d
1260: 65 76 69 63 65 20 69 6e 74 6f 20 62 6c 6f 63 6b  evice into block
1270: 69 6e 67 20 6f 72 20 6e 6f 6e 62 6c 6f 63 6b 69  ing or nonblocki
1280: 6e 67 20 6d 6f 64 65 2e 0a 20 2a 09 43 61 6e 20  ng mode.. *.Can 
1290: 63 61 6c 6c 20 54 63 6c 5f 53 65 74 43 68 61 6e  call Tcl_SetChan
12a0: 6e 65 6c 45 72 72 6f 72 2e 0a 20 2a 0a 20 2a 2d  nelError.. *. *-
12b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
12c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
12d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
12e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
12f0: 2d 2d 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  --. */.static in
1300: 74 20 44 69 67 65 73 74 42 6c 6f 63 6b 4d 6f 64  t DigestBlockMod
1310: 65 50 72 6f 63 28 43 6c 69 65 6e 74 44 61 74 61  eProc(ClientData
1320: 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 69 6e 74   clientData, int
1330: 20 6d 6f 64 65 29 20 7b 0a 20 20 20 20 44 69 67   mode) {.    Dig
1340: 65 73 74 53 74 61 74 65 20 2a 73 74 61 74 65 50  estState *stateP
1350: 74 72 20 3d 20 28 44 69 67 65 73 74 53 74 61 74  tr = (DigestStat
1360: 65 20 2a 29 20 63 6c 69 65 6e 74 44 61 74 61 3b  e *) clientData;
1370: 0a 0a 20 20 20 20 69 66 20 28 6d 6f 64 65 20 3d  ..    if (mode =
1380: 3d 20 54 43 4c 5f 4d 4f 44 45 5f 4e 4f 4e 42 4c  = TCL_MODE_NONBL
1390: 4f 43 4b 49 4e 47 29 20 7b 0a 09 73 74 61 74 65  OCKING) {..state
13a0: 50 74 72 2d 3e 66 6c 61 67 73 20 7c 3d 20 54 4c  Ptr->flags |= TL
13b0: 53 5f 54 43 4c 5f 41 53 59 4e 43 3b 0a 20 20 20  S_TCL_ASYNC;.   
13c0: 20 7d 20 65 6c 73 65 20 7b 0a 09 73 74 61 74 65   } else {..state
13d0: 50 74 72 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28  Ptr->flags &= ~(
13e0: 54 4c 53 5f 54 43 4c 5f 41 53 59 4e 43 29 3b 0a  TLS_TCL_ASYNC);.
13f0: 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e      }.    return
1400: 20 30 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d   0;.}../*. *----
1410: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1420: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1430: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1440: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
1450: 20 2a 0a 20 2a 20 44 69 67 65 73 74 46 72 65 65   *. * DigestFree
1460: 20 2d 2d 0a 20 2a 0a 20 2a 09 54 68 69 73 20 70   --. *. *.This p
1470: 72 6f 63 65 64 75 72 65 20 72 65 6d 6f 76 65 73  rocedure removes
1480: 20 61 20 64 69 67 65 73 74 20 73 74 61 74 65 20   a digest state 
1490: 73 74 72 75 63 74 75 72 65 0a 20 2a 0a 20 2a 20  structure. *. * 
14a0: 52 65 74 75 72 6e 73 3a 0a 20 2a 09 4e 6f 74 68  Returns:. *.Noth
14b0: 69 6e 67 0a 20 2a 0a 20 2a 20 53 69 64 65 20 65  ing. *. * Side e
14c0: 66 66 65 63 74 73 3a 0a 20 2a 09 52 65 6d 6f 76  ffects:. *.Remov
14d0: 65 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 0a  es structure. *.
14e0: 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   *--------------
14f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1500: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1520: 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 76 6f 69 64 20 44  -----. */.void D
1530: 69 67 65 73 74 46 72 65 65 20 28 44 69 67 65 73  igestFree (Diges
1540: 74 53 74 61 74 65 20 2a 73 74 61 74 65 50 74 72  tState *statePtr
1550: 29 20 7b 0a 20 20 20 20 69 66 20 28 73 74 61 74  ) {.    if (stat
1560: 65 50 74 72 20 3d 3d 20 28 44 69 67 65 73 74 53  ePtr == (DigestS
1570: 74 61 74 65 20 2a 29 20 4e 55 4c 4c 29 20 72 65  tate *) NULL) re
1580: 74 75 72 6e 3b 0a 20 20 20 20 0a 20 20 20 20 69  turn;.    .    i
1590: 66 20 28 73 74 61 74 65 50 74 72 2d 3e 63 74 78  f (statePtr->ctx
15a0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 45 56 50   != NULL) {..EVP
15b0: 5f 4d 44 5f 43 54 58 5f 66 72 65 65 28 73 74 61  _MD_CTX_free(sta
15c0: 74 65 50 74 72 2d 3e 63 74 78 29 3b 0a 20 20 20  tePtr->ctx);.   
15d0: 20 7d 0a 20 20 20 20 63 6b 66 72 65 65 28 73 74   }.    ckfree(st
15e0: 61 74 65 50 74 72 29 3b 0a 7d 0a 0a 2f 2a 0a 20  atePtr);.}../*. 
15f0: 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *---------------
1600: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1610: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1620: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1630: 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44 69 67 65 73  ----. *. * Diges
1640: 74 43 6c 6f 73 65 50 72 6f 63 20 2d 2d 0a 20 2a  tCloseProc --. *
1650: 0a 20 2a 09 54 68 69 73 20 70 72 6f 63 65 64 75  . *.This procedu
1660: 72 65 20 69 73 20 69 6e 76 6f 6b 65 64 20 62 79  re is invoked by
1670: 20 74 68 65 20 67 65 6e 65 72 69 63 20 49 4f 20   the generic IO 
1680: 6c 65 76 65 6c 20 74 6f 20 70 65 72 66 6f 72 6d  level to perform
1690: 0a 20 2a 09 63 68 61 6e 6e 65 6c 2d 74 79 70 65  . *.channel-type
16a0: 2d 73 70 65 63 69 66 69 63 20 63 6c 65 61 6e 75  -specific cleanu
16b0: 70 20 77 68 65 6e 20 64 69 67 65 73 74 20 63 68  p when digest ch
16c0: 61 6e 6e 65 6c 20 69 73 20 63 6c 6f 73 65 64 2e  annel is closed.
16d0: 0a 20 2a 0a 20 2a 20 52 65 74 75 72 6e 73 3a 0a  . *. * Returns:.
16e0: 20 2a 09 54 43 4c 5f 4f 4b 20 6f 72 20 54 43 4c   *.TCL_OK or TCL
16f0: 5f 45 52 52 4f 52 0a 20 2a 0a 20 2a 20 53 69 64  _ERROR. *. * Sid
1700: 65 20 65 66 66 65 63 74 73 3a 0a 20 2a 09 57 72  e effects:. *.Wr
1710: 69 74 65 73 20 64 69 67 65 73 74 20 74 6f 20 6f  ites digest to o
1720: 75 74 70 75 74 20 61 6e 64 20 63 6c 6f 73 65 73  utput and closes
1730: 20 74 68 65 20 63 68 61 6e 6e 65 6c 2e 0a 20 2a   the channel.. *
1740: 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  . *-------------
1750: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1760: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1770: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1780: 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 69 6e 74 20 44  ------. */.int D
1790: 69 67 65 73 74 43 6c 6f 73 65 50 72 6f 63 28 43  igestCloseProc(C
17a0: 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74  lientData client
17b0: 44 61 74 61 2c 20 54 63 6c 5f 49 6e 74 65 72 70  Data, Tcl_Interp
17c0: 20 2a 69 6e 74 65 72 70 29 20 7b 0a 20 20 20 20   *interp) {.    
17d0: 44 69 67 65 73 74 53 74 61 74 65 20 2a 73 74 61  DigestState *sta
17e0: 74 65 50 74 72 20 3d 20 28 44 69 67 65 73 74 53  tePtr = (DigestS
17f0: 74 61 74 65 20 2a 29 20 63 6c 69 65 6e 74 44 61  tate *) clientDa
1800: 74 61 3b 0a 20 20 20 20 69 6e 74 20 72 65 73 75  ta;.    int resu
1810: 6c 74 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a 20  lt = 0;..    /* 
1820: 43 61 6e 63 65 6c 20 61 63 74 69 76 65 20 74 69  Cancel active ti
1830: 6d 65 72 2c 20 69 66 20 61 6e 79 20 2a 2f 0a 20  mer, if any */. 
1840: 20 20 20 69 66 20 28 73 74 61 74 65 50 74 72 2d     if (statePtr-
1850: 3e 74 69 6d 65 72 20 21 3d 20 28 54 63 6c 5f 54  >timer != (Tcl_T
1860: 69 6d 65 72 54 6f 6b 65 6e 29 20 4e 55 4c 4c 29  imerToken) NULL)
1870: 20 7b 0a 09 54 63 6c 5f 44 65 6c 65 74 65 54 69   {..Tcl_DeleteTi
1880: 6d 65 72 48 61 6e 64 6c 65 72 28 73 74 61 74 65  merHandler(state
1890: 50 74 72 2d 3e 74 69 6d 65 72 29 3b 0a 09 73 74  Ptr->timer);..st
18a0: 61 74 65 50 74 72 2d 3e 74 69 6d 65 72 20 3d 20  atePtr->timer = 
18b0: 28 54 63 6c 5f 54 69 6d 65 72 54 6f 6b 65 6e 29  (Tcl_TimerToken)
18c0: 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 0a 20 20   NULL;.    }..  
18d0: 20 20 2f 2a 20 43 6c 65 61 6e 2d 75 70 20 2a 2f    /* Clean-up */
18e0: 0a 20 20 20 20 44 69 67 65 73 74 46 72 65 65 28  .    DigestFree(
18f0: 73 74 61 74 65 50 74 72 29 3b 0a 20 20 20 20 72  statePtr);.    r
1900: 65 74 75 72 6e 20 72 65 73 75 6c 74 3b 0a 7d 0a  eturn result;.}.
1910: 0a 2f 2a 0a 20 2a 20 53 61 6d 65 20 61 73 20 44  ./*. * Same as D
1920: 69 67 65 73 74 43 6c 6f 73 65 50 72 6f 63 20 62  igestCloseProc b
1930: 75 74 20 77 69 74 68 20 69 6e 64 69 76 69 64 75  ut with individu
1940: 61 6c 20 72 65 61 64 20 61 6e 64 20 77 72 69 74  al read and writ
1950: 65 20 63 6c 6f 73 65 20 63 6f 6e 74 72 6f 6c 0a  e close control.
1960: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 44   */.static int D
1970: 69 67 65 73 74 43 6c 6f 73 65 32 50 72 6f 63 28  igestClose2Proc(
1980: 43 6c 69 65 6e 74 44 61 74 61 20 69 6e 73 74 61  ClientData insta
1990: 6e 63 65 44 61 74 61 2c 20 54 63 6c 5f 49 6e 74  nceData, Tcl_Int
19a0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
19b0: 20 66 6c 61 67 73 29 20 7b 0a 0a 20 20 20 20 69   flags) {..    i
19c0: 66 20 28 28 66 6c 61 67 73 20 26 20 28 54 43 4c  f ((flags & (TCL
19d0: 5f 43 4c 4f 53 45 5f 52 45 41 44 20 7c 20 54 43  _CLOSE_READ | TC
19e0: 4c 5f 43 4c 4f 53 45 5f 57 52 49 54 45 29 29 20  L_CLOSE_WRITE)) 
19f0: 3d 3d 20 30 29 20 7b 0a 09 72 65 74 75 72 6e 20  == 0) {..return 
1a00: 44 69 67 65 73 74 43 6c 6f 73 65 50 72 6f 63 28  DigestCloseProc(
1a10: 69 6e 73 74 61 6e 63 65 44 61 74 61 2c 20 69 6e  instanceData, in
1a20: 74 65 72 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  terp);.    }.   
1a30: 20 72 65 74 75 72 6e 20 45 49 4e 56 41 4c 3b 0a   return EINVAL;.
1a40: 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d  }../*. *--------
1a50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1a60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1a70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20  --------------. 
1a90: 2a 0a 20 2a 20 44 69 67 65 73 74 49 6e 70 75 74  *. * DigestInput
1aa0: 50 72 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09 43 61  Proc --. *. *.Ca
1ab0: 6c 6c 65 64 20 62 79 20 74 68 65 20 67 65 6e 65  lled by the gene
1ac0: 72 69 63 20 49 4f 20 73 79 73 74 65 6d 20 74 6f  ric IO system to
1ad0: 20 72 65 61 64 20 64 61 74 61 20 66 72 6f 6d 20   read data from 
1ae0: 74 72 61 6e 73 66 6f 72 6d 2e 0a 20 2a 0a 20 2a  transform.. *. *
1af0: 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09 54 6f 74   Returns:. *.Tot
1b00: 61 6c 20 62 79 74 65 73 20 72 65 61 64 0a 20 2a  al bytes read. *
1b10: 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74 73  . * Side effects
1b20: 3a 0a 20 2a 09 52 65 61 64 20 64 61 74 61 20 66  :. *.Read data f
1b30: 72 6f 6d 20 74 72 61 6e 73 66 6f 72 6d 20 61 6e  rom transform an
1b40: 64 20 77 72 69 74 65 20 74 6f 20 62 75 66 0a 20  d write to buf. 
1b50: 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *. *------------
1b60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1b90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 69  ----------. */.i
1ba0: 6e 74 20 44 69 67 65 73 74 49 6e 70 75 74 50 72  nt DigestInputPr
1bb0: 6f 63 28 43 6c 69 65 6e 74 44 61 74 61 20 63 6c  oc(ClientData cl
1bc0: 69 65 6e 74 44 61 74 61 2c 20 63 68 61 72 20 2a  ientData, char *
1bd0: 62 75 66 2c 20 69 6e 74 20 74 6f 52 65 61 64 2c  buf, int toRead,
1be0: 20 69 6e 74 20 2a 65 72 72 6f 72 43 6f 64 65 50   int *errorCodeP
1bf0: 74 72 29 20 7b 0a 20 20 20 20 44 69 67 65 73 74  tr) {.    Digest
1c00: 53 74 61 74 65 20 2a 73 74 61 74 65 50 74 72 20  State *statePtr 
1c10: 3d 20 28 44 69 67 65 73 74 53 74 61 74 65 20 2a  = (DigestState *
1c20: 29 20 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20  ) clientData;.  
1c30: 20 20 54 63 6c 5f 43 68 61 6e 6e 65 6c 20 70 61    Tcl_Channel pa
1c40: 72 65 6e 74 3b 0a 20 20 20 20 69 6e 74 20 72 65  rent;.    int re
1c50: 61 64 3b 0a 20 20 20 20 2a 65 72 72 6f 72 43 6f  ad;.    *errorCo
1c60: 64 65 50 74 72 20 3d 20 30 3b 0a 0a 20 20 20 20  dePtr = 0;..    
1c70: 69 66 20 28 74 6f 52 65 61 64 20 3c 3d 20 30 20  if (toRead <= 0 
1c80: 7c 7c 20 73 74 61 74 65 50 74 72 2d 3e 73 65 6c  || statePtr->sel
1c90: 66 20 3d 3d 20 28 54 63 6c 5f 43 68 61 6e 6e 65  f == (Tcl_Channe
1ca0: 6c 29 20 4e 55 4c 4c 29 20 7b 0a 09 72 65 74 75  l) NULL) {..retu
1cb0: 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  rn 0;.    }..   
1cc0: 20 2f 2a 20 47 65 74 20 62 79 74 65 73 20 66 72   /* Get bytes fr
1cd0: 6f 6d 20 75 6e 64 65 72 6c 79 69 6e 67 20 63 68  om underlying ch
1ce0: 61 6e 6e 65 6c 20 2a 2f 0a 20 20 20 20 70 61 72  annel */.    par
1cf0: 65 6e 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 61  ent = Tcl_GetSta
1d00: 63 6b 65 64 43 68 61 6e 6e 65 6c 28 73 74 61 74  ckedChannel(stat
1d10: 65 50 74 72 2d 3e 73 65 6c 66 29 3b 0a 20 20 20  ePtr->self);.   
1d20: 20 72 65 61 64 20 3d 20 54 63 6c 5f 52 65 61 64   read = Tcl_Read
1d30: 52 61 77 28 70 61 72 65 6e 74 2c 20 62 75 66 2c  Raw(parent, buf,
1d40: 20 74 6f 52 65 61 64 29 3b 0a 0a 20 20 20 20 2f   toRead);..    /
1d50: 2a 20 41 64 64 20 74 6f 20 6d 65 73 73 61 67 65  * Add to message
1d60: 20 64 69 67 65 73 74 20 2a 2f 0a 20 20 20 20 69   digest */.    i
1d70: 66 20 28 72 65 61 64 20 3e 20 30 29 20 7b 0a 09  f (read > 0) {..
1d80: 2f 2a 20 4f 4b 20 2a 2f 0a 09 69 66 20 28 21 45  /* OK */..if (!E
1d90: 56 50 5f 44 69 67 65 73 74 55 70 64 61 74 65 28  VP_DigestUpdate(
1da0: 73 74 61 74 65 50 74 72 2d 3e 63 74 78 2c 20 62  statePtr->ctx, b
1db0: 75 66 2c 20 72 65 61 64 29 29 20 7b 0a 09 20 20  uf, read)) {..  
1dc0: 20 20 54 63 6c 5f 53 65 74 43 68 61 6e 6e 65 6c    Tcl_SetChannel
1dd0: 45 72 72 6f 72 28 73 74 61 74 65 50 74 72 2d 3e  Error(statePtr->
1de0: 73 65 6c 66 2c 20 54 63 6c 5f 4f 62 6a 50 72 69  self, Tcl_ObjPri
1df0: 6e 74 66 28 22 44 69 67 65 73 74 20 75 70 64 61  ntf("Digest upda
1e00: 74 65 20 66 61 69 6c 65 64 3a 20 25 73 22 2c 20  te failed: %s", 
1e10: 52 45 41 53 4f 4e 28 29 29 29 3b 0a 09 20 20 20  REASON()));..   
1e20: 20 2a 65 72 72 6f 72 43 6f 64 65 50 74 72 20 3d   *errorCodePtr =
1e30: 20 45 49 4e 56 41 4c 3b 0a 09 20 20 20 20 72 65   EINVAL;..    re
1e40: 74 75 72 6e 20 2d 31 3b 0a 09 7d 0a 09 2a 65 72  turn -1;..}..*er
1e50: 72 6f 72 43 6f 64 65 50 74 72 20 3d 20 45 41 47  rorCodePtr = EAG
1e60: 41 49 4e 3b 0a 09 72 65 61 64 20 3d 20 2d 31 3b  AIN;..read = -1;
1e70: 0a 09 20 20 20 20 0a 20 20 20 20 7d 20 65 6c 73  ..    .    } els
1e80: 65 20 69 66 20 28 72 65 61 64 20 3c 20 30 29 20  e if (read < 0) 
1e90: 7b 0a 09 2f 2a 20 45 72 72 6f 72 20 2a 2f 0a 09  {../* Error */..
1ea0: 2a 65 72 72 6f 72 43 6f 64 65 50 74 72 20 3d 20  *errorCodePtr = 
1eb0: 54 63 6c 5f 47 65 74 45 72 72 6e 6f 28 29 3b 0a  Tcl_GetErrno();.
1ec0: 0a 20 20 20 20 7d 20 65 6c 73 65 20 69 66 20 28  .    } else if (
1ed0: 21 28 73 74 61 74 65 50 74 72 2d 3e 66 6c 61 67  !(statePtr->flag
1ee0: 73 20 26 20 30 78 31 30 29 29 20 7b 0a 09 2f 2a  s & 0x10)) {../*
1ef0: 20 45 4f 46 20 2a 2f 0a 09 2a 65 72 72 6f 72 43   EOF */..*errorC
1f00: 6f 64 65 50 74 72 20 3d 20 30 3b 0a 09 75 6e 73  odePtr = 0;..uns
1f10: 69 67 6e 65 64 20 63 68 61 72 20 6d 64 5f 62 75  igned char md_bu
1f20: 66 5b 45 56 50 5f 4d 41 58 5f 4d 44 5f 53 49 5a  f[EVP_MAX_MD_SIZ
1f30: 45 5d 3b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e  E];..unsigned in
1f40: 74 20 6d 64 5f 6c 65 6e 20 3d 20 30 3b 0a 0a 09  t md_len = 0;...
1f50: 2f 2a 20 47 65 74 20 6d 65 73 73 61 67 65 20 64  /* Get message d
1f60: 69 67 65 73 74 20 2a 2f 0a 09 69 66 20 28 21 45  igest */..if (!E
1f70: 56 50 5f 44 69 67 65 73 74 46 69 6e 61 6c 5f 65  VP_DigestFinal_e
1f80: 78 28 73 74 61 74 65 50 74 72 2d 3e 63 74 78 2c  x(statePtr->ctx,
1f90: 20 6d 64 5f 62 75 66 2c 20 26 6d 64 5f 6c 65 6e   md_buf, &md_len
1fa0: 29 29 20 7b 0a 09 20 20 20 20 2a 65 72 72 6f 72  )) {..    *error
1fb0: 43 6f 64 65 50 74 72 20 3d 20 45 49 4e 56 41 4c  CodePtr = EINVAL
1fc0: 3b 0a 0a 09 2f 2a 20 57 72 69 74 65 20 6d 65 73  ;.../* Write mes
1fd0: 73 61 67 65 20 64 69 67 65 73 74 20 74 6f 20 6f  sage digest to o
1fe0: 75 74 70 75 74 20 63 68 61 6e 6e 65 6c 20 61 73  utput channel as
1ff0: 20 62 79 74 65 20 61 72 72 61 79 20 6f 72 20 68   byte array or h
2000: 65 78 20 73 74 72 69 6e 67 20 2a 2f 0a 09 7d 20  ex string */..} 
2010: 65 6c 73 65 20 69 66 20 28 6d 64 5f 6c 65 6e 20  else if (md_len 
2020: 3e 20 30 29 20 7b 0a 09 20 20 20 20 69 66 20 28  > 0) {..    if (
2030: 73 74 61 74 65 50 74 72 2d 3e 66 6f 72 6d 61 74  statePtr->format
2040: 20 3d 3d 20 42 49 4e 5f 46 4f 52 4d 41 54 29 20   == BIN_FORMAT) 
2050: 7b 0a 09 09 72 65 61 64 20 3d 20 6d 64 5f 6c 65  {...read = md_le
2060: 6e 3b 0a 09 09 6d 65 6d 63 70 79 28 62 75 66 2c  n;...memcpy(buf,
2070: 20 6d 64 5f 62 75 66 2c 20 72 65 61 64 29 3b 0a   md_buf, read);.
2080: 0a 09 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09  ..    } else {..
2090: 09 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 68  .unsigned char h
20a0: 65 78 5f 62 75 66 5b 45 56 50 5f 4d 41 58 5f 4d  ex_buf[EVP_MAX_M
20b0: 44 5f 53 49 5a 45 2a 32 5d 3b 0a 09 09 75 6e 73  D_SIZE*2];...uns
20c0: 69 67 6e 65 64 20 63 68 61 72 20 2a 70 74 72 20  igned char *ptr 
20d0: 3d 20 68 65 78 5f 62 75 66 3b 0a 0a 09 09 66 6f  = hex_buf;....fo
20e0: 72 20 28 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  r (unsigned int 
20f0: 69 20 3d 20 30 3b 20 69 20 3c 20 6d 64 5f 6c 65  i = 0; i < md_le
2100: 6e 3b 20 69 2b 2b 29 20 7b 0a 09 09 20 20 20 20  n; i++) {...    
2110: 2a 70 74 72 2b 2b 20 3d 20 68 65 78 5b 28 6d 64  *ptr++ = hex[(md
2120: 5f 62 75 66 5b 69 5d 20 3e 3e 20 34 29 20 26 20  _buf[i] >> 4) & 
2130: 30 78 30 46 5d 3b 0a 09 09 20 20 20 20 2a 70 74  0x0F];...    *pt
2140: 72 2b 2b 20 3d 20 68 65 78 5b 6d 64 5f 62 75 66  r++ = hex[md_buf
2150: 5b 69 5d 20 26 20 30 78 30 46 5d 3b 0a 09 09 7d  [i] & 0x0F];...}
2160: 0a 09 09 72 65 61 64 20 3d 20 6d 64 5f 6c 65 6e  ...read = md_len
2170: 2a 32 3b 0a 09 09 6d 65 6d 63 70 79 28 62 75 66  *2;...memcpy(buf
2180: 2c 20 68 65 78 5f 62 75 66 2c 20 72 65 61 64 29  , hex_buf, read)
2190: 3b 0a 09 20 20 20 20 7d 0a 09 7d 0a 09 73 74 61  ;..    }..}..sta
21a0: 74 65 50 74 72 2d 3e 66 6c 61 67 73 20 7c 3d 20  tePtr->flags |= 
21b0: 30 78 31 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20  0x10;.    }.    
21c0: 72 65 74 75 72 6e 20 72 65 61 64 3b 0a 7d 0a 0a  return read;.}..
21d0: 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  /*. *-----------
21e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
21f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2200: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a 20  -----------. *. 
2220: 2a 20 44 69 67 65 73 74 4f 75 74 70 75 74 50 72  * DigestOutputPr
2230: 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09 43 61 6c 6c  oc --. *. *.Call
2240: 65 64 20 62 79 20 74 68 65 20 67 65 6e 65 72 69  ed by the generi
2250: 63 20 49 4f 20 73 79 73 74 65 6d 20 74 6f 20 77  c IO system to w
2260: 72 69 74 65 20 64 61 74 61 20 74 6f 20 74 72 61  rite data to tra
2270: 6e 73 66 6f 72 6d 2e 0a 20 2a 0a 20 2a 20 52 65  nsform.. *. * Re
2280: 74 75 72 6e 73 3a 0a 20 2a 09 54 6f 74 61 6c 20  turns:. *.Total 
2290: 62 79 74 65 73 20 77 72 69 74 74 65 6e 0a 20 2a  bytes written. *
22a0: 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74 73  . * Side effects
22b0: 3a 0a 20 2a 09 47 65 74 20 64 61 74 61 20 66 72  :. *.Get data fr
22c0: 6f 6d 20 62 75 66 20 61 6e 64 20 75 70 64 61 74  om buf and updat
22d0: 65 20 64 69 67 65 73 74 0a 20 2a 0a 20 2a 2d 2d  e digest. *. *--
22e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
22f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2320: 2d 2d 2d 2d 0a 20 2a 2f 0a 20 69 6e 74 20 44 69  ----. */. int Di
2330: 67 65 73 74 4f 75 74 70 75 74 50 72 6f 63 28 43  gestOutputProc(C
2340: 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74  lientData client
2350: 44 61 74 61 2c 20 63 6f 6e 73 74 20 63 68 61 72  Data, const char
2360: 20 2a 62 75 66 2c 20 69 6e 74 20 74 6f 57 72 69   *buf, int toWri
2370: 74 65 2c 20 69 6e 74 20 2a 65 72 72 6f 72 43 6f  te, int *errorCo
2380: 64 65 50 74 72 29 20 7b 0a 20 20 20 20 44 69 67  dePtr) {.    Dig
2390: 65 73 74 53 74 61 74 65 20 2a 73 74 61 74 65 50  estState *stateP
23a0: 74 72 20 3d 20 28 44 69 67 65 73 74 53 74 61 74  tr = (DigestStat
23b0: 65 20 2a 29 20 63 6c 69 65 6e 74 44 61 74 61 3b  e *) clientData;
23c0: 0a 20 20 20 20 2a 65 72 72 6f 72 43 6f 64 65 50  .    *errorCodeP
23d0: 74 72 20 3d 20 30 3b 0a 0a 20 20 20 20 69 66 20  tr = 0;..    if 
23e0: 28 74 6f 57 72 69 74 65 20 3c 3d 20 30 20 7c 7c  (toWrite <= 0 ||
23f0: 20 73 74 61 74 65 50 74 72 2d 3e 73 65 6c 66 20   statePtr->self 
2400: 3d 3d 20 28 54 63 6c 5f 43 68 61 6e 6e 65 6c 29  == (Tcl_Channel)
2410: 20 4e 55 4c 4c 29 20 7b 0a 09 72 65 74 75 72 6e   NULL) {..return
2420: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65   0;.    }.    re
2430: 74 75 72 6e 20 74 6f 57 72 69 74 65 3b 0a 7d 0a  turn toWrite;.}.
2440: 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ./*. *----------
2450: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2460: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2470: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2480: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a  ------------. *.
2490: 20 2a 20 44 69 67 65 73 74 53 65 74 4f 70 74 69   * DigestSetOpti
24a0: 6f 6e 50 72 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09  onProc --. *. *.
24b0: 43 61 6c 6c 65 64 20 62 79 20 74 68 65 20 67 65  Called by the ge
24c0: 6e 65 72 69 63 20 49 4f 20 73 79 73 74 65 6d 20  neric IO system 
24d0: 74 6f 20 73 65 74 20 63 68 61 6e 6e 65 6c 20 6f  to set channel o
24e0: 70 74 69 6f 6e 20 74 6f 20 76 61 6c 75 65 2e 0a  ption to value..
24f0: 20 2a 0a 20 2a 20 52 65 74 75 72 6e 73 3a 0a 20   *. * Returns:. 
2500: 2a 09 54 43 4c 5f 4f 4b 20 69 66 20 73 75 63 63  *.TCL_OK if succ
2510: 65 73 73 66 75 6c 20 6f 72 20 54 43 4c 5f 45 52  essful or TCL_ER
2520: 52 4f 52 20 69 66 20 66 61 69 6c 65 64 2e 0a 20  ROR if failed.. 
2530: 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74  *. * Side effect
2540: 73 3a 0a 20 2a 09 55 70 64 61 74 65 73 20 63 68  s:. *.Updates ch
2550: 61 6e 6e 65 6c 20 6f 70 74 69 6f 6e 20 74 6f 20  annel option to 
2560: 6e 65 77 20 76 61 6c 75 65 2e 0a 20 2a 0a 20 2a  new value.. *. *
2570: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2580: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2590: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25b0: 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 73 74 61 74 69  ------. */.stati
25c0: 63 20 69 6e 74 20 44 69 67 65 73 74 53 65 74 4f  c int DigestSetO
25d0: 70 74 69 6f 6e 50 72 6f 63 28 43 6c 69 65 6e 74  ptionProc(Client
25e0: 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c  Data clientData,
25f0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
2600: 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  erp, const char 
2610: 2a 6f 70 74 69 6f 6e 4e 61 6d 65 2c 0a 09 63 6f  *optionName,..co
2620: 6e 73 74 20 63 68 61 72 20 2a 6f 70 74 69 6f 6e  nst char *option
2630: 56 61 6c 75 65 29 20 7b 0a 20 20 20 20 44 69 67  Value) {.    Dig
2640: 65 73 74 53 74 61 74 65 20 2a 73 74 61 74 65 50  estState *stateP
2650: 74 72 20 3d 20 28 44 69 67 65 73 74 53 74 61 74  tr = (DigestStat
2660: 65 20 2a 29 20 63 6c 69 65 6e 74 44 61 74 61 3b  e *) clientData;
2670: 0a 20 20 20 20 54 63 6c 5f 43 68 61 6e 6e 65 6c  .    Tcl_Channel
2680: 20 70 61 72 65 6e 74 3b 0a 20 20 20 20 54 63 6c   parent;.    Tcl
2690: 5f 44 72 69 76 65 72 53 65 74 4f 70 74 69 6f 6e  _DriverSetOption
26a0: 50 72 6f 63 20 2a 73 65 74 4f 70 74 69 6f 6e 50  Proc *setOptionP
26b0: 72 6f 63 3b 0a 0a 20 20 20 20 69 66 20 28 73 74  roc;..    if (st
26c0: 61 74 65 50 74 72 2d 3e 73 65 6c 66 20 3d 3d 20  atePtr->self == 
26d0: 28 54 63 6c 5f 43 68 61 6e 6e 65 6c 29 20 4e 55  (Tcl_Channel) NU
26e0: 4c 4c 29 20 7b 0a 09 72 65 74 75 72 6e 20 54 43  LL) {..return TC
26f0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a  L_ERROR;.    }..
2700: 20 20 20 20 2f 2a 20 44 65 6c 65 67 61 74 65 20      /* Delegate 
2710: 6f 70 74 69 6f 6e 73 20 64 6f 77 6e 73 74 72 65  options downstre
2720: 61 6d 20 2a 2f 0a 20 20 20 20 70 61 72 65 6e 74  am */.    parent
2730: 20 3d 20 54 63 6c 5f 47 65 74 53 74 61 63 6b 65   = Tcl_GetStacke
2740: 64 43 68 61 6e 6e 65 6c 28 73 74 61 74 65 50 74  dChannel(statePt
2750: 72 2d 3e 73 65 6c 66 29 3b 0a 20 20 20 20 73 65  r->self);.    se
2760: 74 4f 70 74 69 6f 6e 50 72 6f 63 20 3d 20 54 63  tOptionProc = Tc
2770: 6c 5f 43 68 61 6e 6e 65 6c 53 65 74 4f 70 74 69  l_ChannelSetOpti
2780: 6f 6e 50 72 6f 63 28 54 63 6c 5f 47 65 74 43 68  onProc(Tcl_GetCh
2790: 61 6e 6e 65 6c 54 79 70 65 28 70 61 72 65 6e 74  annelType(parent
27a0: 29 29 3b 0a 20 20 20 20 69 66 20 28 73 65 74 4f  ));.    if (setO
27b0: 70 74 69 6f 6e 50 72 6f 63 20 21 3d 20 4e 55 4c  ptionProc != NUL
27c0: 4c 29 20 7b 0a 09 72 65 74 75 72 6e 20 28 2a 73  L) {..return (*s
27d0: 65 74 4f 70 74 69 6f 6e 50 72 6f 63 29 28 54 63  etOptionProc)(Tc
27e0: 6c 5f 47 65 74 43 68 61 6e 6e 65 6c 49 6e 73 74  l_GetChannelInst
27f0: 61 6e 63 65 44 61 74 61 28 70 61 72 65 6e 74 29  anceData(parent)
2800: 2c 20 69 6e 74 65 72 70 2c 20 6f 70 74 69 6f 6e  , interp, option
2810: 4e 61 6d 65 2c 20 6f 70 74 69 6f 6e 56 61 6c 75  Name, optionValu
2820: 65 29 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  e);.    } else {
2830: 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52  ..return TCL_ERR
2840: 4f 52 3b 0a 20 20 20 20 7d 0a 7d 0a 0a 2f 2a 0a  OR;.    }.}../*.
2850: 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   *--------------
2860: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2870: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2880: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2890: 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44  --------. *. * D
28a0: 69 67 65 73 74 47 65 74 4f 70 74 69 6f 6e 50 72  igestGetOptionPr
28b0: 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09 43 61 6c 6c  oc --. *. *.Call
28c0: 65 64 20 62 79 20 74 68 65 20 67 65 6e 65 72 69  ed by the generi
28d0: 63 20 49 4f 20 73 79 73 74 65 6d 20 74 6f 20 67  c IO system to g
28e0: 65 74 20 63 68 61 6e 6e 65 6c 20 6f 70 74 69 6f  et channel optio
28f0: 6e 27 73 20 76 61 6c 75 65 2e 0a 20 2a 0a 20 2a  n's value.. *. *
2900: 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09 54 43 4c   Returns:. *.TCL
2910: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
2920: 6c 20 6f 72 20 54 43 4c 5f 45 52 52 4f 52 20 69  l or TCL_ERROR i
2930: 66 20 66 61 69 6c 65 64 2e 0a 20 2a 0a 20 2a 20  f failed.. *. * 
2940: 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a 20 2a  Side effects:. *
2950: 09 53 65 74 73 20 72 65 73 75 6c 74 20 74 6f 20  .Sets result to 
2960: 6f 70 74 69 6f 6e 27 73 20 76 61 6c 75 65 0a 20  option's value. 
2970: 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *. *------------
2980: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2990: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 73  ----------. */.s
29c0: 74 61 74 69 63 20 69 6e 74 20 44 69 67 65 73 74  tatic int Digest
29d0: 47 65 74 4f 70 74 69 6f 6e 50 72 6f 63 28 43 6c  GetOptionProc(Cl
29e0: 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44  ientData clientD
29f0: 61 74 61 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20  ata, Tcl_Interp 
2a00: 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63  *interp, const c
2a10: 68 61 72 20 2a 6f 70 74 69 6f 6e 4e 61 6d 65 2c  har *optionName,
2a20: 0a 09 54 63 6c 5f 44 53 74 72 69 6e 67 20 2a 6f  ..Tcl_DString *o
2a30: 70 74 69 6f 6e 56 61 6c 75 65 29 20 7b 0a 20 20  ptionValue) {.  
2a40: 20 20 44 69 67 65 73 74 53 74 61 74 65 20 2a 73    DigestState *s
2a50: 74 61 74 65 50 74 72 20 3d 20 28 44 69 67 65 73  tatePtr = (Diges
2a60: 74 53 74 61 74 65 20 2a 29 20 63 6c 69 65 6e 74  tState *) client
2a70: 44 61 74 61 3b 0a 20 20 20 20 54 63 6c 5f 43 68  Data;.    Tcl_Ch
2a80: 61 6e 6e 65 6c 20 70 61 72 65 6e 74 3b 0a 20 20  annel parent;.  
2a90: 20 20 54 63 6c 5f 44 72 69 76 65 72 47 65 74 4f    Tcl_DriverGetO
2aa0: 70 74 69 6f 6e 50 72 6f 63 20 2a 67 65 74 4f 70  ptionProc *getOp
2ab0: 74 69 6f 6e 50 72 6f 63 3b 0a 0a 20 20 20 20 69  tionProc;..    i
2ac0: 66 20 28 73 74 61 74 65 50 74 72 2d 3e 73 65 6c  f (statePtr->sel
2ad0: 66 20 3d 3d 20 28 54 63 6c 5f 43 68 61 6e 6e 65  f == (Tcl_Channe
2ae0: 6c 29 20 4e 55 4c 4c 29 20 7b 0a 09 72 65 74 75  l) NULL) {..retu
2af0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
2b00: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 44 65 6c 65    }..    /* Dele
2b10: 67 61 74 65 20 6f 70 74 69 6f 6e 73 20 64 6f 77  gate options dow
2b20: 6e 73 74 72 65 61 6d 20 2a 2f 0a 20 20 20 20 70  nstream */.    p
2b30: 61 72 65 6e 74 20 3d 20 54 63 6c 5f 47 65 74 53  arent = Tcl_GetS
2b40: 74 61 63 6b 65 64 43 68 61 6e 6e 65 6c 28 73 74  tackedChannel(st
2b50: 61 74 65 50 74 72 2d 3e 73 65 6c 66 29 3b 0a 20  atePtr->self);. 
2b60: 20 20 20 67 65 74 4f 70 74 69 6f 6e 50 72 6f 63     getOptionProc
2b70: 20 3d 20 54 63 6c 5f 43 68 61 6e 6e 65 6c 47 65   = Tcl_ChannelGe
2b80: 74 4f 70 74 69 6f 6e 50 72 6f 63 28 54 63 6c 5f  tOptionProc(Tcl_
2b90: 47 65 74 43 68 61 6e 6e 65 6c 54 79 70 65 28 70  GetChannelType(p
2ba0: 61 72 65 6e 74 29 29 3b 0a 20 20 20 20 69 66 20  arent));.    if 
2bb0: 28 67 65 74 4f 70 74 69 6f 6e 50 72 6f 63 20 21  (getOptionProc !
2bc0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 72 65 74 75 72  = NULL) {..retur
2bd0: 6e 20 28 2a 67 65 74 4f 70 74 69 6f 6e 50 72 6f  n (*getOptionPro
2be0: 63 29 28 54 63 6c 5f 47 65 74 43 68 61 6e 6e 65  c)(Tcl_GetChanne
2bf0: 6c 49 6e 73 74 61 6e 63 65 44 61 74 61 28 70 61  lInstanceData(pa
2c00: 72 65 6e 74 29 2c 20 69 6e 74 65 72 70 2c 20 6f  rent), interp, o
2c10: 70 74 69 6f 6e 4e 61 6d 65 2c 20 6f 70 74 69 6f  ptionName, optio
2c20: 6e 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 20 65  nValue);.    } e
2c30: 6c 73 65 20 69 66 20 28 6f 70 74 69 6f 6e 4e 61  lse if (optionNa
2c40: 6d 65 20 3d 3d 20 28 63 68 61 72 2a 29 20 4e 55  me == (char*) NU
2c50: 4c 4c 29 20 7b 0a 09 2f 2a 20 52 65 71 75 65 73  LL) {../* Reques
2c60: 74 20 69 73 20 71 75 65 72 79 20 66 6f 72 20 61  t is query for a
2c70: 6c 6c 20 6f 70 74 69 6f 6e 73 2c 20 74 68 69 73  ll options, this
2c80: 20 69 73 20 6f 6b 2e 20 2a 2f 0a 09 72 65 74 75   is ok. */..retu
2c90: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20 20 20 20 7d  rn TCL_OK;.    }
2ca0: 0a 0a 20 20 20 20 2f 2a 20 52 65 71 75 65 73 74  ..    /* Request
2cb0: 20 66 6f 72 20 61 20 73 70 65 63 69 66 69 63 20   for a specific 
2cc0: 6f 70 74 69 6f 6e 20 68 61 73 20 74 6f 20 66 61  option has to fa
2cd0: 69 6c 2c 20 77 65 20 64 6f 6e 27 74 20 68 61 76  il, we don't hav
2ce0: 65 20 61 6e 79 2e 20 2a 2f 0a 20 20 20 20 72 65  e any. */.    re
2cf0: 74 75 72 6e 20 54 63 6c 5f 42 61 64 43 68 61 6e  turn Tcl_BadChan
2d00: 6e 65 6c 4f 70 74 69 6f 6e 28 69 6e 74 65 72 70  nelOption(interp
2d10: 2c 20 6f 70 74 69 6f 6e 4e 61 6d 65 2c 20 22 22  , optionName, ""
2d20: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d  );.}../*. *-----
2d30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2d40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2d50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2d60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2d70: 2d 0a 20 2a 0a 20 2a 20 44 69 67 65 73 74 54 69  -. *. * DigestTi
2d80: 6d 65 72 48 61 6e 64 6c 65 72 20 2d 2d 0a 20 2a  merHandler --. *
2d90: 0a 20 2a 09 43 61 6c 6c 65 64 20 62 79 20 74 68  . *.Called by th
2da0: 65 20 6e 6f 74 69 66 69 65 72 20 76 69 61 20 74  e notifier via t
2db0: 69 6d 65 72 20 74 6f 20 66 6c 75 73 68 20 6f 75  imer to flush ou
2dc0: 74 20 70 65 6e 64 69 6e 67 20 69 6e 70 75 74 20  t pending input 
2dd0: 64 61 74 61 2e 0a 20 2a 0a 20 2a 20 52 65 74 75  data.. *. * Retu
2de0: 72 6e 73 3a 0a 20 2a 09 4e 6f 74 68 69 6e 67 0a  rns:. *.Nothing.
2df0: 20 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63   *. * Side effec
2e00: 74 73 3a 0a 20 2a 09 4d 61 79 20 63 61 6c 6c 20  ts:. *.May call 
2e10: 54 63 6c 5f 4e 6f 74 69 66 79 43 68 61 6e 6e 65  Tcl_NotifyChanne
2e20: 6c 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d  l. *. *---------
2e30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a  -------------. *
2e70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 44 69  /.static void Di
2e80: 67 65 73 74 54 69 6d 65 72 48 61 6e 64 6c 65 72  gestTimerHandler
2e90: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65  (ClientData clie
2ea0: 6e 74 44 61 74 61 29 20 7b 0a 20 20 20 20 44 69  ntData) {.    Di
2eb0: 67 65 73 74 53 74 61 74 65 20 2a 73 74 61 74 65  gestState *state
2ec0: 50 74 72 20 3d 20 28 44 69 67 65 73 74 53 74 61  Ptr = (DigestSta
2ed0: 74 65 20 2a 29 20 63 6c 69 65 6e 74 44 61 74 61  te *) clientData
2ee0: 3b 0a 0a 20 20 20 20 69 66 20 28 73 74 61 74 65  ;..    if (state
2ef0: 50 74 72 2d 3e 73 65 6c 66 20 3d 3d 20 28 54 63  Ptr->self == (Tc
2f00: 6c 5f 43 68 61 6e 6e 65 6c 29 20 4e 55 4c 4c 29  l_Channel) NULL)
2f10: 20 7b 0a 09 72 65 74 75 72 6e 3b 0a 20 20 20 20   {..return;.    
2f20: 7d 0a 0a 20 20 20 20 2f 2a 20 43 6c 65 61 72 20  }..    /* Clear 
2f30: 74 69 6d 65 72 20 74 6f 6b 65 6e 20 2a 2f 0a 20  timer token */. 
2f40: 20 20 20 73 74 61 74 65 50 74 72 2d 3e 74 69 6d     statePtr->tim
2f50: 65 72 20 3d 20 28 54 63 6c 5f 54 69 6d 65 72 54  er = (Tcl_TimerT
2f60: 6f 6b 65 6e 29 20 4e 55 4c 4c 3b 0a 0a 20 20 20  oken) NULL;..   
2f70: 20 2f 2a 20 46 69 72 65 20 65 76 65 6e 74 20 69   /* Fire event i
2f80: 66 20 74 68 65 72 65 20 69 73 20 70 65 6e 64 69  f there is pendi
2f90: 6e 67 20 64 61 74 61 2c 20 73 6b 69 70 20 6f 74  ng data, skip ot
2fa0: 68 65 72 77 69 73 65 20 2a 2f 0a 20 20 20 20 69  herwise */.    i
2fb0: 66 20 28 28 73 74 61 74 65 50 74 72 2d 3e 77 61  f ((statePtr->wa
2fc0: 74 63 68 4d 61 73 6b 20 26 20 54 43 4c 5f 52 45  tchMask & TCL_RE
2fd0: 41 44 41 42 4c 45 29 20 26 26 20 28 54 63 6c 5f  ADABLE) && (Tcl_
2fe0: 49 6e 70 75 74 42 75 66 66 65 72 65 64 28 73 74  InputBuffered(st
2ff0: 61 74 65 50 74 72 2d 3e 73 65 6c 66 29 20 3e 20  atePtr->self) > 
3000: 30 29 29 20 7b 0a 09 54 63 6c 5f 4e 6f 74 69 66  0)) {..Tcl_Notif
3010: 79 43 68 61 6e 6e 65 6c 28 73 74 61 74 65 50 74  yChannel(statePt
3020: 72 2d 3e 73 65 6c 66 2c 20 54 43 4c 5f 52 45 41  r->self, TCL_REA
3030: 44 41 42 4c 45 29 3b 0a 20 20 20 20 7d 0a 7d 0a  DABLE);.    }.}.
3040: 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ./*. *----------
3050: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3060: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3070: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3080: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a  ------------. *.
3090: 20 2a 20 44 69 67 65 73 74 57 61 74 63 68 50 72   * DigestWatchPr
30a0: 6f 63 20 2d 2d 0a 20 2a 0a 20 2a 09 49 6e 69 74  oc --. *. *.Init
30b0: 69 61 6c 69 7a 65 20 74 68 65 20 6e 6f 74 69 66  ialize the notif
30c0: 69 65 72 20 74 6f 20 77 61 74 63 68 20 66 6f 72  ier to watch for
30d0: 20 65 76 65 6e 74 73 20 66 72 6f 6d 20 74 68 69   events from thi
30e0: 73 20 63 68 61 6e 6e 65 6c 2e 0a 20 2a 0a 20 2a  s channel.. *. *
30f0: 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09 4e 6f 74   Returns:. *.Not
3100: 68 69 6e 67 0a 20 2a 0a 20 2a 20 53 69 64 65 20  hing. *. * Side 
3110: 65 66 66 65 63 74 73 3a 0a 20 2a 09 43 6f 6e 66  effects:. *.Conf
3120: 69 67 75 72 65 20 6e 6f 74 69 66 69 65 72 20 73  igure notifier s
3130: 6f 20 66 75 74 75 72 65 20 65 76 65 6e 74 73 20  o future events 
3140: 6f 6e 20 74 68 65 20 63 68 61 6e 6e 65 6c 20 77  on the channel w
3150: 69 6c 6c 20 62 65 20 73 65 65 6e 20 62 79 20 54  ill be seen by T
3160: 63 6c 2e 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d  cl.. *. *-------
3170: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3180: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3190: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
31a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
31b0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 52 45 41 44   */.#define READ
31c0: 5f 44 45 4c 41 59 09 35 0a 76 6f 69 64 20 44 69  _DELAY.5.void Di
31d0: 67 65 73 74 57 61 74 63 68 50 72 6f 63 28 43 6c  gestWatchProc(Cl
31e0: 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44  ientData clientD
31f0: 61 74 61 2c 20 69 6e 74 20 6d 61 73 6b 29 20 7b  ata, int mask) {
3200: 0a 20 20 20 20 44 69 67 65 73 74 53 74 61 74 65  .    DigestState
3210: 20 2a 73 74 61 74 65 50 74 72 20 3d 20 28 44 69   *statePtr = (Di
3220: 67 65 73 74 53 74 61 74 65 20 2a 29 20 63 6c 69  gestState *) cli
3230: 65 6e 74 44 61 74 61 3b 0a 20 20 20 20 54 63 6c  entData;.    Tcl
3240: 5f 43 68 61 6e 6e 65 6c 20 70 61 72 65 6e 74 3b  _Channel parent;
3250: 0a 20 20 20 20 54 63 6c 5f 44 72 69 76 65 72 57  .    Tcl_DriverW
3260: 61 74 63 68 50 72 6f 63 20 2a 77 61 74 63 68 50  atchProc *watchP
3270: 72 6f 63 3b 0a 0a 20 20 20 20 69 66 20 28 73 74  roc;..    if (st
3280: 61 74 65 50 74 72 2d 3e 73 65 6c 66 20 3d 3d 20  atePtr->self == 
3290: 28 54 63 6c 5f 43 68 61 6e 6e 65 6c 29 20 4e 55  (Tcl_Channel) NU
32a0: 4c 4c 29 20 7b 0a 09 72 65 74 75 72 6e 3b 0a 20  LL) {..return;. 
32b0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 74 6f     }..    /* Sto
32c0: 72 65 20 4f 52 2d 65 64 20 63 6f 6d 62 69 6e 61  re OR-ed combina
32d0: 74 69 6f 6e 20 6f 66 20 54 43 4c 5f 52 45 41 44  tion of TCL_READ
32e0: 41 42 4c 45 2c 20 54 43 4c 5f 57 52 49 54 41 42  ABLE, TCL_WRITAB
32f0: 4c 45 20 61 6e 64 20 54 43 4c 5f 45 58 43 45 50  LE and TCL_EXCEP
3300: 54 49 4f 4e 20 2a 2f 0a 20 20 20 20 73 74 61 74  TION */.    stat
3310: 65 50 74 72 2d 3e 77 61 74 63 68 4d 61 73 6b 20  ePtr->watchMask 
3320: 3d 20 6d 61 73 6b 3b 0a 0a 20 20 20 20 2f 2a 20  = mask;..    /* 
3330: 50 72 6f 70 61 67 61 74 65 20 6d 61 73 6b 20 69  Propagate mask i
3340: 6e 66 6f 20 74 6f 20 70 61 72 65 6e 74 20 63 68  nfo to parent ch
3350: 61 6e 6e 65 6c 20 2a 2f 0a 20 20 20 20 70 61 72  annel */.    par
3360: 65 6e 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 61  ent = Tcl_GetSta
3370: 63 6b 65 64 43 68 61 6e 6e 65 6c 28 73 74 61 74  ckedChannel(stat
3380: 65 50 74 72 2d 3e 73 65 6c 66 29 3b 0a 20 20 20  ePtr->self);.   
3390: 20 77 61 74 63 68 50 72 6f 63 20 3d 20 54 63 6c   watchProc = Tcl
33a0: 5f 43 68 61 6e 6e 65 6c 57 61 74 63 68 50 72 6f  _ChannelWatchPro
33b0: 63 28 54 63 6c 5f 47 65 74 43 68 61 6e 6e 65 6c  c(Tcl_GetChannel
33c0: 54 79 70 65 28 70 61 72 65 6e 74 29 29 3b 0a 20  Type(parent));. 
33d0: 20 20 20 77 61 74 63 68 50 72 6f 63 28 54 63 6c     watchProc(Tcl
33e0: 5f 47 65 74 43 68 61 6e 6e 65 6c 49 6e 73 74 61  _GetChannelInsta
33f0: 6e 63 65 44 61 74 61 28 70 61 72 65 6e 74 29 2c  nceData(parent),
3400: 20 6d 61 73 6b 29 3b 0a 0a 20 20 20 20 2f 2a 20   mask);..    /* 
3410: 52 65 6d 6f 76 65 20 70 65 6e 64 69 6e 67 20 74  Remove pending t
3420: 69 6d 65 72 20 2a 2f 0a 20 20 20 20 69 66 20 28  imer */.    if (
3430: 73 74 61 74 65 50 74 72 2d 3e 74 69 6d 65 72 20  statePtr->timer 
3440: 21 3d 20 28 54 63 6c 5f 54 69 6d 65 72 54 6f 6b  != (Tcl_TimerTok
3450: 65 6e 29 20 4e 55 4c 4c 29 20 7b 0a 09 54 63 6c  en) NULL) {..Tcl
3460: 5f 44 65 6c 65 74 65 54 69 6d 65 72 48 61 6e 64  _DeleteTimerHand
3470: 6c 65 72 28 73 74 61 74 65 50 74 72 2d 3e 74 69  ler(statePtr->ti
3480: 6d 65 72 29 3b 0a 09 73 74 61 74 65 50 74 72 2d  mer);..statePtr-
3490: 3e 74 69 6d 65 72 20 3d 20 28 54 63 6c 5f 54 69  >timer = (Tcl_Ti
34a0: 6d 65 72 54 6f 6b 65 6e 29 20 4e 55 4c 4c 3b 0a  merToken) NULL;.
34b0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
34c0: 20 74 68 65 72 65 20 69 73 20 64 61 74 61 20 70   there is data p
34d0: 65 6e 64 69 6e 67 2c 20 73 65 74 20 6e 65 77 20  ending, set new 
34e0: 74 69 6d 65 72 20 74 6f 20 63 61 6c 6c 20 54 63  timer to call Tc
34f0: 6c 5f 4e 6f 74 69 66 79 43 68 61 6e 6e 65 6c 20  l_NotifyChannel 
3500: 2a 2f 0a 20 20 20 20 69 66 20 28 28 6d 61 73 6b  */.    if ((mask
3510: 20 26 20 54 43 4c 5f 52 45 41 44 41 42 4c 45 29   & TCL_READABLE)
3520: 20 26 26 20 28 54 63 6c 5f 49 6e 70 75 74 42 75   && (Tcl_InputBu
3530: 66 66 65 72 65 64 28 73 74 61 74 65 50 74 72 2d  ffered(statePtr-
3540: 3e 73 65 6c 66 29 20 3e 20 30 29 29 20 7b 0a 09  >self) > 0)) {..
3550: 73 74 61 74 65 50 74 72 2d 3e 74 69 6d 65 72 20  statePtr->timer 
3560: 3d 20 54 63 6c 5f 43 72 65 61 74 65 54 69 6d 65  = Tcl_CreateTime
3570: 72 48 61 6e 64 6c 65 72 28 52 45 41 44 5f 44 45  rHandler(READ_DE
3580: 4c 41 59 2c 20 44 69 67 65 73 74 54 69 6d 65 72  LAY, DigestTimer
3590: 48 61 6e 64 6c 65 72 2c 20 28 43 6c 69 65 6e 74  Handler, (Client
35a0: 44 61 74 61 29 20 73 74 61 74 65 50 74 72 29 3b  Data) statePtr);
35b0: 0a 20 20 20 20 7d 0a 7d 0a 0a 2f 2a 0a 20 2a 2d  .    }.}../*. *-
35c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
35d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
35e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
35f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3600: 2d 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44 69 67 65  -----. *. * Dige
3610: 73 74 47 65 74 48 61 6e 64 6c 65 50 72 6f 63 20  stGetHandleProc 
3620: 2d 2d 0a 20 2a 0a 20 2a 09 43 61 6c 6c 65 64 20  --. *. *.Called 
3630: 66 72 6f 6d 20 54 63 6c 5f 47 65 74 43 68 61 6e  from Tcl_GetChan
3640: 6e 65 6c 48 61 6e 64 6c 65 20 74 6f 20 72 65 74  nelHandle to ret
3650: 72 69 65 76 65 20 4f 53 20 73 70 65 63 69 66 69  rieve OS specifi
3660: 63 20 66 69 6c 65 20 68 61 6e 64 6c 65 0a 20 2a  c file handle. *
3670: 09 66 72 6f 6d 20 69 6e 73 69 64 65 20 74 68 69  .from inside thi
3680: 73 20 63 68 61 6e 6e 65 6c 2e 20 4e 6f 74 20 75  s channel. Not u
3690: 73 65 64 20 66 6f 72 20 74 72 61 6e 73 66 6f 72  sed for transfor
36a0: 6d 61 74 69 6f 6e 73 3f 0a 20 2a 0a 20 2a 20 52  mations?. *. * R
36b0: 65 74 75 72 6e 73 3a 0a 20 2a 09 49 66 20 64 69  eturns:. *.If di
36c0: 72 65 63 74 69 6f 6e 20 69 73 20 54 43 4c 5f 52  rection is TCL_R
36d0: 45 41 44 41 42 4c 45 20 72 65 74 75 72 6e 20 74  EADABLE return t
36e0: 68 65 20 68 61 6e 64 6c 65 20 75 73 65 64 20 66  he handle used f
36f0: 6f 72 20 69 6e 70 75 74 2c 20 6f 72 20 69 66 0a  or input, or if.
3700: 20 2a 09 54 43 4c 5f 57 52 49 54 41 42 4c 45 20   *.TCL_WRITABLE 
3710: 72 65 74 75 72 6e 20 74 68 65 20 68 61 6e 64 6c  return the handl
3720: 65 20 75 73 65 64 20 66 6f 72 20 6f 75 74 70 75  e used for outpu
3730: 74 2e 0a 20 2a 0a 20 2a 20 53 69 64 65 20 65 66  t.. *. * Side ef
3740: 66 65 63 74 73 3a 0a 20 2a 09 4e 6f 6e 65 0a 20  fects:. *.None. 
3750: 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *. *------------
3760: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3770: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3780: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3790: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 69  ----------. */.i
37a0: 6e 74 20 44 69 67 65 73 74 47 65 74 48 61 6e 64  nt DigestGetHand
37b0: 6c 65 50 72 6f 63 28 43 6c 69 65 6e 74 44 61 74  leProc(ClientDat
37c0: 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 69 6e  a clientData, in
37d0: 74 20 64 69 72 65 63 74 69 6f 6e 2c 20 43 6c 69  t direction, Cli
37e0: 65 6e 74 44 61 74 61 20 2a 68 61 6e 64 6c 65 50  entData *handleP
37f0: 74 72 29 20 7b 0a 20 20 20 20 44 69 67 65 73 74  tr) {.    Digest
3800: 53 74 61 74 65 20 2a 73 74 61 74 65 50 74 72 20  State *statePtr 
3810: 3d 20 28 44 69 67 65 73 74 53 74 61 74 65 20 2a  = (DigestState *
3820: 29 20 63 6c 69 65 6e 74 44 61 74 61 3b 0a 0a 20  ) clientData;.. 
3830: 20 20 20 69 66 20 28 73 74 61 74 65 50 74 72 2d     if (statePtr-
3840: 3e 73 65 6c 66 20 3d 3d 20 28 54 63 6c 5f 43 68  >self == (Tcl_Ch
3850: 61 6e 6e 65 6c 29 20 4e 55 4c 4c 29 20 7b 0a 09  annel) NULL) {..
3860: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
3870: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ;.    }.    retu
3880: 72 6e 20 54 63 6c 5f 47 65 74 43 68 61 6e 6e 65  rn Tcl_GetChanne
3890: 6c 48 61 6e 64 6c 65 28 54 63 6c 5f 47 65 74 53  lHandle(Tcl_GetS
38a0: 74 61 63 6b 65 64 43 68 61 6e 6e 65 6c 28 73 74  tackedChannel(st
38b0: 61 74 65 50 74 72 2d 3e 73 65 6c 66 29 2c 20 64  atePtr->self), d
38c0: 69 72 65 63 74 69 6f 6e 2c 20 68 61 6e 64 6c 65  irection, handle
38d0: 50 74 72 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d  Ptr);.}../*. *--
38e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
38f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3900: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3920: 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44 69 67 65 73  ----. *. * Diges
3930: 74 4e 6f 74 69 66 79 50 72 6f 63 20 2d 2d 0a 20  tNotifyProc --. 
3940: 2a 0a 20 2a 09 43 61 6c 6c 65 64 20 62 79 20 54  *. *.Called by T
3950: 63 6c 20 74 6f 20 69 6e 66 6f 72 6d 20 75 73 20  cl to inform us 
3960: 6f 66 20 61 63 74 69 76 69 74 79 20 6f 6e 20 74  of activity on t
3970: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 63 68  he underlying ch
3980: 61 6e 6e 65 6c 2e 0a 20 2a 0a 20 2a 20 52 65 74  annel.. *. * Ret
3990: 75 72 6e 73 3a 0a 20 2a 09 55 6e 63 68 61 6e 67  urns:. *.Unchang
39a0: 65 64 20 69 6e 74 65 72 65 73 74 4d 61 73 6b 20  ed interestMask 
39b0: 77 68 69 63 68 20 69 73 20 61 6e 20 4f 52 2d 65  which is an OR-e
39c0: 64 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 20 6f 66  d combination of
39d0: 20 54 43 4c 5f 52 45 41 44 41 42 4c 45 20 6f 72   TCL_READABLE or
39e0: 20 54 43 4c 5f 57 52 49 54 41 42 4c 45 0a 20 2a   TCL_WRITABLE. *
39f0: 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74 73  . * Side effects
3a00: 3a 0a 20 2a 09 43 61 6e 63 65 6c 73 20 61 6e 79  :. *.Cancels any
3a10: 20 70 65 6e 64 69 6e 67 20 74 69 6d 65 72 2e 0a   pending timer..
3a20: 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   *. *-----------
3a30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a  -----------. */.
3a70: 69 6e 74 20 44 69 67 65 73 74 4e 6f 74 69 66 79  int DigestNotify
3a80: 50 72 6f 63 28 43 6c 69 65 6e 74 44 61 74 61 20  Proc(ClientData 
3a90: 63 6c 69 65 6e 74 44 61 74 61 2c 20 69 6e 74 20  clientData, int 
3aa0: 69 6e 74 65 72 65 73 74 4d 61 73 6b 29 20 7b 0a  interestMask) {.
3ab0: 20 20 20 20 44 69 67 65 73 74 53 74 61 74 65 20      DigestState 
3ac0: 2a 73 74 61 74 65 50 74 72 20 3d 20 28 44 69 67  *statePtr = (Dig
3ad0: 65 73 74 53 74 61 74 65 20 2a 29 20 63 6c 69 65  estState *) clie
3ae0: 6e 74 44 61 74 61 3b 0a 0a 20 20 20 20 2f 2a 20  ntData;..    /* 
3af0: 53 6b 69 70 20 74 69 6d 65 72 20 65 76 65 6e 74  Skip timer event
3b00: 20 61 73 20 72 65 64 75 6e 64 61 6e 74 20 2a 2f   as redundant */
3b10: 0a 20 20 20 20 69 66 20 28 73 74 61 74 65 50 74  .    if (statePt
3b20: 72 2d 3e 74 69 6d 65 72 20 21 3d 20 28 54 63 6c  r->timer != (Tcl
3b30: 5f 54 69 6d 65 72 54 6f 6b 65 6e 29 20 4e 55 4c  _TimerToken) NUL
3b40: 4c 29 20 7b 0a 09 54 63 6c 5f 44 65 6c 65 74 65  L) {..Tcl_Delete
3b50: 54 69 6d 65 72 48 61 6e 64 6c 65 72 28 73 74 61  TimerHandler(sta
3b60: 74 65 50 74 72 2d 3e 74 69 6d 65 72 29 3b 0a 09  tePtr->timer);..
3b70: 73 74 61 74 65 50 74 72 2d 3e 74 69 6d 65 72 20  statePtr->timer 
3b80: 3d 20 28 54 63 6c 5f 54 69 6d 65 72 54 6f 6b 65  = (Tcl_TimerToke
3b90: 6e 29 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20  n) NULL;.    }. 
3ba0: 20 20 20 72 65 74 75 72 6e 20 69 6e 74 65 72 65     return intere
3bb0: 73 74 4d 61 73 6b 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  stMask;.}../*. *
3bc0: 0a 20 2a 20 43 68 61 6e 6e 65 6c 20 74 79 70 65  . * Channel type
3bd0: 20 73 74 72 75 63 74 75 72 65 20 64 65 66 69 6e   structure defin
3be0: 69 74 69 6f 6e 20 66 6f 72 20 64 69 67 65 73 74  ition for digest
3bf0: 20 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 73   transformations
3c00: 2e 0a 20 2a 0a 20 2a 2f 0a 73 74 61 74 69 63 20  .. *. */.static 
3c10: 63 6f 6e 73 74 20 54 63 6c 5f 43 68 61 6e 6e 65  const Tcl_Channe
3c20: 6c 54 79 70 65 20 64 69 67 65 73 74 43 68 61 6e  lType digestChan
3c30: 6e 65 6c 54 79 70 65 20 3d 20 7b 0a 20 20 20 20  nelType = {.    
3c40: 22 64 69 67 65 73 74 22 2c 09 09 09 2f 2a 20 54  "digest",.../* T
3c50: 79 70 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 20 20  ype name */.    
3c60: 54 43 4c 5f 43 48 41 4e 4e 45 4c 5f 56 45 52 53  TCL_CHANNEL_VERS
3c70: 49 4f 4e 5f 35 2c 09 2f 2a 20 76 35 20 63 68 61  ION_5,./* v5 cha
3c80: 6e 6e 65 6c 20 2a 2f 0a 20 20 20 20 44 69 67 65  nnel */.    Dige
3c90: 73 74 43 6c 6f 73 65 50 72 6f 63 2c 09 09 2f 2a  stCloseProc,../*
3ca0: 20 43 6c 6f 73 65 20 70 72 6f 63 20 2a 2f 0a 20   Close proc */. 
3cb0: 20 20 20 44 69 67 65 73 74 49 6e 70 75 74 50 72     DigestInputPr
3cc0: 6f 63 2c 09 09 2f 2a 20 49 6e 70 75 74 20 70 72  oc,../* Input pr
3cd0: 6f 63 20 2a 2f 0a 20 20 20 20 44 69 67 65 73 74  oc */.    Digest
3ce0: 4f 75 74 70 75 74 50 72 6f 63 2c 09 09 2f 2a 20  OutputProc,../* 
3cf0: 4f 75 74 70 75 74 20 70 72 6f 63 20 2a 2f 0a 20  Output proc */. 
3d00: 20 20 20 4e 55 4c 4c 2c 09 09 09 2f 2a 20 53 65     NULL,.../* Se
3d10: 65 6b 20 70 72 6f 63 20 2a 2f 0a 20 20 20 20 44  ek proc */.    D
3d20: 69 67 65 73 74 53 65 74 4f 70 74 69 6f 6e 50 72  igestSetOptionPr
3d30: 6f 63 2c 09 2f 2a 20 53 65 74 20 6f 70 74 69 6f  oc,./* Set optio
3d40: 6e 20 70 72 6f 63 20 2a 2f 0a 20 20 20 20 44 69  n proc */.    Di
3d50: 67 65 73 74 47 65 74 4f 70 74 69 6f 6e 50 72 6f  gestGetOptionPro
3d60: 63 2c 09 2f 2a 20 47 65 74 20 6f 70 74 69 6f 6e  c,./* Get option
3d70: 20 70 72 6f 63 20 2a 2f 0a 20 20 20 20 44 69 67   proc */.    Dig
3d80: 65 73 74 57 61 74 63 68 50 72 6f 63 2c 09 09 2f  estWatchProc,../
3d90: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 6e 6f 74  * Initialize not
3da0: 69 66 69 65 72 20 2a 2f 0a 20 20 20 20 44 69 67  ifier */.    Dig
3db0: 65 73 74 47 65 74 48 61 6e 64 6c 65 50 72 6f 63  estGetHandleProc
3dc0: 2c 09 2f 2a 20 47 65 74 20 4f 53 20 68 61 6e 64  ,./* Get OS hand
3dd0: 6c 65 73 20 6f 75 74 20 6f 66 20 63 68 61 6e 6e  les out of chann
3de0: 65 6c 20 2a 2f 0a 20 20 20 20 44 69 67 65 73 74  el */.    Digest
3df0: 43 6c 6f 73 65 32 50 72 6f 63 2c 09 09 2f 2a 20  Close2Proc,../* 
3e00: 63 6c 6f 73 65 32 70 72 6f 63 20 2a 2f 0a 20 20  close2proc */.  
3e10: 20 20 44 69 67 65 73 74 42 6c 6f 63 6b 4d 6f 64    DigestBlockMod
3e20: 65 50 72 6f 63 2c 09 2f 2a 20 53 65 74 20 62 6c  eProc,./* Set bl
3e30: 6f 63 6b 69 6e 67 2f 6e 6f 6e 62 6c 6f 63 6b 69  ocking/nonblocki
3e40: 6e 67 20 6d 6f 64 65 2a 2f 0a 20 20 20 20 4e 55  ng mode*/.    NU
3e50: 4c 4c 2c 09 09 09 2f 2a 20 46 6c 75 73 68 20 70  LL,.../* Flush p
3e60: 72 6f 63 20 2a 2f 0a 20 20 20 20 44 69 67 65 73  roc */.    Diges
3e70: 74 4e 6f 74 69 66 79 50 72 6f 63 2c 09 09 2f 2a  tNotifyProc,../*
3e80: 20 48 61 6e 64 6c 69 6e 67 20 6f 66 20 65 76 65   Handling of eve
3e90: 6e 74 73 20 62 75 62 62 6c 69 6e 67 20 75 70 20  nts bubbling up 
3ea0: 2a 2f 0a 20 20 20 20 4e 55 4c 4c 2c 09 09 09 2f  */.    NULL,.../
3eb0: 2a 20 57 69 64 65 20 73 65 65 6b 20 70 72 6f 63  * Wide seek proc
3ec0: 20 2a 2f 0a 20 20 20 20 4e 55 4c 4c 2c 09 09 09   */.    NULL,...
3ed0: 2f 2a 20 54 68 72 65 61 64 20 61 63 74 69 6f 6e  /* Thread action
3ee0: 20 2a 2f 0a 20 20 20 20 4e 55 4c 4c 09 09 09 2f   */.    NULL.../
3ef0: 2a 20 54 72 75 6e 63 61 74 65 20 2a 2f 0a 7d 3b  * Truncate */.};
3f00: 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d  ../*. *---------
3f10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a  -------------. *
3f50: 0a 20 2a 20 44 69 67 65 73 74 43 68 61 6e 6e 65  . * DigestChanne
3f60: 6c 20 2d 2d 0a 20 2a 0a 20 2a 09 43 72 65 61 74  l --. *. *.Creat
3f70: 65 20 61 20 73 74 61 63 6b 65 64 20 63 68 61 6e  e a stacked chan
3f80: 6e 65 6c 20 66 6f 72 20 61 20 6d 65 73 73 61 67  nel for a messag
3f90: 65 20 64 69 67 65 73 74 20 74 72 61 6e 73 66 6f  e digest transfo
3fa0: 72 6d 61 74 69 6f 6e 2e 0a 20 2a 0a 20 2a 20 52  rmation.. *. * R
3fb0: 65 74 75 72 6e 73 3a 0a 20 2a 09 54 43 4c 5f 4f  eturns:. *.TCL_O
3fc0: 4b 20 6f 72 20 54 43 4c 5f 45 52 52 4f 52 0a 20  K or TCL_ERROR. 
3fd0: 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74  *. * Side effect
3fe0: 73 3a 0a 20 2a 09 41 64 64 73 20 74 72 61 6e 73  s:. *.Adds trans
3ff0: 66 6f 72 6d 20 74 6f 20 63 68 61 6e 6e 65 6c 20  form to channel 
4000: 61 6e 64 20 73 65 74 73 20 72 65 73 75 6c 74 20  and sets result 
4010: 74 6f 20 63 68 61 6e 6e 65 6c 20 6e 61 6d 65 20  to channel name 
4020: 6f 72 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  or error message
4030: 2e 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d  .. *. *---------
4040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4050: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4060: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4070: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a  -------------. *
4080: 2f 0a 73 74 61 74 69 63 20 69 6e 74 0a 44 69 67  /.static int.Dig
4090: 65 73 74 43 68 61 6e 6e 65 6c 28 54 63 6c 5f 49  estChannel(Tcl_I
40a0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
40b0: 6f 6e 73 74 20 63 68 61 72 20 2a 63 68 61 6e 6e  onst char *chann
40c0: 65 6c 2c 20 63 6f 6e 73 74 20 45 56 50 5f 4d 44  el, const EVP_MD
40d0: 20 2a 6d 64 2c 20 69 6e 74 20 66 6f 72 6d 61 74   *md, int format
40e0: 29 20 7b 0a 20 20 20 20 69 6e 74 20 6d 6f 64 65  ) {.    int mode
40f0: 3b 20 2f 2a 20 4f 52 2d 65 64 20 63 6f 6d 62 69  ; /* OR-ed combi
4100: 6e 61 74 69 6f 6e 20 6f 66 20 54 43 4c 5f 52 45  nation of TCL_RE
4110: 41 44 41 42 4c 45 20 61 6e 64 20 54 43 4c 5f 57  ADABLE and TCL_W
4120: 52 49 54 41 42 4c 45 20 2a 2f 0a 20 20 20 20 54  RITABLE */.    T
4130: 63 6c 5f 43 68 61 6e 6e 65 6c 20 63 68 61 6e 3b  cl_Channel chan;
4140: 0a 20 20 20 20 45 56 50 5f 4d 44 5f 43 54 58 20  .    EVP_MD_CTX 
4150: 2a 63 74 78 3b 0a 20 20 20 20 44 69 67 65 73 74  *ctx;.    Digest
4160: 53 74 61 74 65 20 2a 73 74 61 74 65 50 74 72 3b  State *statePtr;
4170: 0a 0a 20 20 20 20 2f 2a 20 56 61 6c 69 64 61 74  ..    /* Validat
4180: 65 20 61 72 67 73 20 2a 2f 0a 20 20 20 20 69 66  e args */.    if
4190: 20 28 63 68 61 6e 6e 65 6c 20 3d 3d 20 28 63 6f   (channel == (co
41a0: 6e 73 74 20 63 68 61 72 20 2a 29 20 4e 55 4c 4c  nst char *) NULL
41b0: 20 7c 7c 20 6d 64 20 3d 3d 20 28 63 6f 6e 73 74   || md == (const
41c0: 20 45 56 50 5f 4d 44 20 2a 29 20 4e 55 4c 4c 29   EVP_MD *) NULL)
41d0: 20 7b 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f 45   {..return TCL_E
41e0: 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  RROR;.    }..   
41f0: 20 63 68 61 6e 20 3d 20 54 63 6c 5f 47 65 74 43   chan = Tcl_GetC
4200: 68 61 6e 6e 65 6c 28 69 6e 74 65 72 70 2c 20 63  hannel(interp, c
4210: 68 61 6e 6e 65 6c 2c 20 26 6d 6f 64 65 29 3b 0a  hannel, &mode);.
4220: 20 20 20 20 69 66 20 28 63 68 61 6e 20 3d 3d 20      if (chan == 
4230: 28 54 63 6c 5f 43 68 61 6e 6e 65 6c 29 20 4e 55  (Tcl_Channel) NU
4240: 4c 4c 29 20 7b 0a 09 72 65 74 75 72 6e 20 54 43  LL) {..return TC
4250: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a  L_ERROR;.    }..
4260: 20 20 20 20 2f 2a 20 4d 61 6b 65 20 73 75 72 65      /* Make sure
4270: 20 74 6f 20 6f 70 65 72 61 74 65 20 6f 6e 20 74   to operate on t
4280: 68 65 20 74 6f 70 6d 6f 73 74 20 63 68 61 6e 6e  he topmost chann
4290: 65 6c 20 2a 2f 0a 20 20 20 20 63 68 61 6e 20 3d  el */.    chan =
42a0: 20 54 63 6c 5f 47 65 74 54 6f 70 43 68 61 6e 6e   Tcl_GetTopChann
42b0: 65 6c 28 63 68 61 6e 29 3b 0a 0a 20 20 20 20 2f  el(chan);..    /
42c0: 2a 20 43 72 65 61 74 65 20 69 6e 74 65 72 6e 61  * Create interna
42d0: 6c 20 73 74 6f 72 61 67 65 20 73 74 72 75 63 74  l storage struct
42e0: 75 72 65 73 20 2a 2f 0a 20 20 20 20 63 74 78 20  ures */.    ctx 
42f0: 3d 20 45 56 50 5f 4d 44 5f 43 54 58 5f 6e 65 77  = EVP_MD_CTX_new
4300: 28 29 3b 0a 20 20 20 20 73 74 61 74 65 50 74 72  ();.    statePtr
4310: 20 3d 20 28 44 69 67 65 73 74 53 74 61 74 65 20   = (DigestState 
4320: 2a 29 20 63 6b 61 6c 6c 6f 63 28 28 75 6e 73 69  *) ckalloc((unsi
4330: 67 6e 65 64 29 20 73 69 7a 65 6f 66 28 44 69 67  gned) sizeof(Dig
4340: 65 73 74 53 74 61 74 65 29 29 3b 0a 20 20 20 20  estState));.    
4350: 69 66 20 28 63 74 78 20 21 3d 20 4e 55 4c 4c 20  if (ctx != NULL 
4360: 26 26 20 73 74 61 74 65 50 74 72 20 21 3d 20 4e  && statePtr != N
4370: 55 4c 4c 29 20 7b 0a 09 6d 65 6d 73 65 74 28 73  ULL) {..memset(s
4380: 74 61 74 65 50 74 72 2c 20 30 2c 20 73 69 7a 65  tatePtr, 0, size
4390: 6f 66 28 44 69 67 65 73 74 53 74 61 74 65 29 29  of(DigestState))
43a0: 3b 0a 09 73 74 61 74 65 50 74 72 2d 3e 73 65 6c  ;..statePtr->sel
43b0: 66 09 3d 20 63 68 61 6e 3b 09 09 2f 2a 20 54 68  f.= chan;../* Th
43c0: 69 73 20 73 6f 63 6b 65 74 20 63 68 61 6e 6e 65  is socket channe
43d0: 6c 20 2a 2f 0a 09 73 74 61 74 65 50 74 72 2d 3e  l */..statePtr->
43e0: 74 69 6d 65 72 20 3d 20 28 54 63 6c 5f 54 69 6d  timer = (Tcl_Tim
43f0: 65 72 54 6f 6b 65 6e 29 20 4e 55 4c 4c 3b 09 2f  erToken) NULL;./
4400: 2a 20 54 69 6d 65 72 20 74 6f 20 66 6c 75 73 68  * Timer to flush
4410: 20 64 61 74 61 20 2a 2f 0a 09 73 74 61 74 65 50   data */..stateP
4420: 74 72 2d 3e 66 6c 61 67 73 20 3d 20 30 3b 09 09  tr->flags = 0;..
4430: 2f 2a 20 43 68 61 6e 20 63 6f 6e 66 69 67 20 66  /* Chan config f
4440: 6c 61 67 73 20 2a 2f 0a 09 73 74 61 74 65 50 74  lags */..statePt
4450: 72 2d 3e 77 61 74 63 68 4d 61 73 6b 20 3d 20 30  r->watchMask = 0
4460: 3b 09 2f 2a 20 43 75 72 72 65 6e 74 20 57 61 74  ;./* Current Wat
4470: 63 68 50 72 6f 63 20 6d 61 73 6b 20 2a 2f 0a 09  chProc mask */..
4480: 73 74 61 74 65 50 74 72 2d 3e 6d 6f 64 65 09 3d  statePtr->mode.=
4490: 20 6d 6f 64 65 3b 09 09 2f 2a 20 43 75 72 72 65   mode;../* Curre
44a0: 6e 74 20 6d 6f 64 65 20 6f 66 20 70 61 72 65 6e  nt mode of paren
44b0: 74 20 63 68 61 6e 6e 65 6c 20 2a 2f 0a 09 73 74  t channel */..st
44c0: 61 74 65 50 74 72 2d 3e 66 6f 72 6d 61 74 20 3d  atePtr->format =
44d0: 20 66 6f 72 6d 61 74 3b 09 2f 2a 20 4f 75 74 70   format;./* Outp
44e0: 75 74 20 66 6f 72 6d 61 74 20 2a 2f 0a 09 73 74  ut format */..st
44f0: 61 74 65 50 74 72 2d 3e 69 6e 74 65 72 70 20 3d  atePtr->interp =
4500: 20 69 6e 74 65 72 70 3b 09 2f 2a 20 43 75 72 72   interp;./* Curr
4510: 65 6e 74 20 69 6e 74 65 72 70 72 65 74 65 72 20  ent interpreter 
4520: 2a 2f 0a 09 73 74 61 74 65 50 74 72 2d 3e 63 74  */..statePtr->ct
4530: 78 20 3d 20 63 74 78 3b 09 09 2f 2a 20 53 53 4c  x = ctx;../* SSL
4540: 20 43 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 20 20   Context */.    
4550: 7d 20 65 6c 73 65 20 7b 0a 09 54 63 6c 5f 41 70  } else {..Tcl_Ap
4560: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
4570: 70 2c 20 22 49 6e 69 74 69 61 6c 69 7a 65 20 64  p, "Initialize d
4580: 69 67 65 73 74 20 65 72 72 6f 72 3a 20 6d 65 6d  igest error: mem
4590: 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66  ory allocation f
45a0: 61 69 6c 75 72 65 22 2c 20 28 63 68 61 72 20 2a  ailure", (char *
45b0: 29 20 4e 55 4c 4c 29 3b 0a 09 45 56 50 5f 4d 44  ) NULL);..EVP_MD
45c0: 5f 43 54 58 5f 66 72 65 65 28 63 74 78 29 3b 0a  _CTX_free(ctx);.
45d0: 09 44 69 67 65 73 74 46 72 65 65 28 73 74 61 74  .DigestFree(stat
45e0: 65 50 74 72 29 3b 0a 09 72 65 74 75 72 6e 20 54  ePtr);..return T
45f0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a  CL_ERROR;.    }.
4600: 0a 20 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69  .    /* Initiali
4610: 7a 65 20 64 69 67 65 73 74 20 2a 2f 0a 23 69 66  ze digest */.#if
4620: 20 4f 50 45 4e 53 53 4c 5f 56 45 52 53 49 4f 4e   OPENSSL_VERSION
4630: 5f 4e 55 4d 42 45 52 20 3c 20 30 78 33 30 30 30  _NUMBER < 0x3000
4640: 30 30 30 30 4c 0a 20 20 20 20 69 66 20 28 21 45  0000L.    if (!E
4650: 56 50 5f 44 69 67 65 73 74 49 6e 69 74 5f 65 78  VP_DigestInit_ex
4660: 28 63 74 78 2c 20 6d 64 2c 20 4e 55 4c 4c 29 29  (ctx, md, NULL))
4670: 0a 23 65 6c 73 65 0a 20 20 20 20 69 66 20 28 21  .#else.    if (!
4680: 45 56 50 5f 44 69 67 65 73 74 49 6e 69 74 5f 65  EVP_DigestInit_e
4690: 78 32 28 63 74 78 2c 20 6d 64 2c 20 4e 55 4c 4c  x2(ctx, md, NULL
46a0: 29 29 0a 23 65 6e 64 69 66 0a 20 20 20 20 7b 0a  )).#endif.    {.
46b0: 09 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c  .Tcl_AppendResul
46c0: 74 28 69 6e 74 65 72 70 2c 20 22 49 6e 69 74 69  t(interp, "Initi
46d0: 61 6c 69 7a 65 20 64 69 67 65 73 74 20 65 72 72  alize digest err
46e0: 6f 72 3a 20 22 2c 20 52 45 41 53 4f 4e 28 29 2c  or: ", REASON(),
46f0: 20 28 63 68 61 72 20 2a 29 20 4e 55 4c 4c 29 3b   (char *) NULL);
4700: 0a 09 45 56 50 5f 4d 44 5f 43 54 58 5f 66 72 65  ..EVP_MD_CTX_fre
4710: 65 28 63 74 78 29 3b 0a 09 44 69 67 65 73 74 46  e(ctx);..DigestF
4720: 72 65 65 28 73 74 61 74 65 50 74 72 29 3b 0a 09  ree(statePtr);..
4730: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
4740: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
4750: 43 6f 6e 66 69 67 75 72 65 20 63 68 61 6e 6e 65  Configure channe
4760: 6c 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 53 65 74  l */.    Tcl_Set
4770: 43 68 61 6e 6e 65 6c 4f 70 74 69 6f 6e 28 69 6e  ChannelOption(in
4780: 74 65 72 70 2c 20 63 68 61 6e 2c 20 22 2d 74 72  terp, chan, "-tr
4790: 61 6e 73 6c 61 74 69 6f 6e 22 2c 20 22 62 69 6e  anslation", "bin
47a0: 61 72 79 22 29 3b 0a 20 20 20 20 69 66 20 28 54  ary");.    if (T
47b0: 63 6c 5f 47 65 74 43 68 61 6e 6e 65 6c 42 75 66  cl_GetChannelBuf
47c0: 66 65 72 53 69 7a 65 28 63 68 61 6e 29 20 3c 20  ferSize(chan) < 
47d0: 45 56 50 5f 4d 41 58 5f 4d 44 5f 53 49 5a 45 20  EVP_MAX_MD_SIZE 
47e0: 2a 20 32 29 20 7b 0a 09 54 63 6c 5f 53 65 74 43  * 2) {..Tcl_SetC
47f0: 68 61 6e 6e 65 6c 42 75 66 66 65 72 53 69 7a 65  hannelBufferSize
4800: 28 63 68 61 6e 2c 20 45 56 50 5f 4d 41 58 5f 4d  (chan, EVP_MAX_M
4810: 44 5f 53 49 5a 45 20 2a 20 32 29 3b 0a 20 20 20  D_SIZE * 2);.   
4820: 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 74 61 63 6b   }..    /* Stack
4830: 20 63 68 61 6e 6e 65 6c 20 2a 2f 0a 20 20 20 20   channel */.    
4840: 73 74 61 74 65 50 74 72 2d 3e 73 65 6c 66 20 3d  statePtr->self =
4850: 20 54 63 6c 5f 53 74 61 63 6b 43 68 61 6e 6e 65   Tcl_StackChanne
4860: 6c 28 69 6e 74 65 72 70 2c 20 26 64 69 67 65 73  l(interp, &diges
4870: 74 43 68 61 6e 6e 65 6c 54 79 70 65 2c 20 28 43  tChannelType, (C
4880: 6c 69 65 6e 74 44 61 74 61 29 20 73 74 61 74 65  lientData) state
4890: 50 74 72 2c 20 6d 6f 64 65 2c 20 63 68 61 6e 29  Ptr, mode, chan)
48a0: 3b 0a 20 20 20 20 69 66 20 28 73 74 61 74 65 50  ;.    if (stateP
48b0: 74 72 2d 3e 73 65 6c 66 20 3d 3d 20 28 54 63 6c  tr->self == (Tcl
48c0: 5f 43 68 61 6e 6e 65 6c 29 20 4e 55 4c 4c 29 20  _Channel) NULL) 
48d0: 7b 0a 09 45 56 50 5f 4d 44 5f 43 54 58 5f 66 72  {..EVP_MD_CTX_fr
48e0: 65 65 28 63 74 78 29 3b 0a 09 44 69 67 65 73 74  ee(ctx);..Digest
48f0: 46 72 65 65 28 73 74 61 74 65 50 74 72 29 3b 0a  Free(statePtr);.
4900: 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f  .return TCL_ERRO
4910: 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 54 63  R;.    }..    Tc
4920: 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65  l_SetResult(inte
4930: 72 70 2c 20 28 63 68 61 72 20 2a 29 20 54 63 6c  rp, (char *) Tcl
4940: 5f 47 65 74 43 68 61 6e 6e 65 6c 4e 61 6d 65 28  _GetChannelName(
4950: 63 68 61 6e 29 2c 20 54 43 4c 5f 56 4f 4c 41 54  chan), TCL_VOLAT
4960: 49 4c 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ILE);.    return
4970: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 2a 2a   TCL_OK;.}../***
4980: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4990: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49c0: 2f 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d  /../*. *--------
49d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
49e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
49f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4a00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a 20  -----------. *. 
4a10: 2a 20 44 69 67 65 73 74 48 61 73 68 46 75 6e 63  * DigestHashFunc
4a20: 74 69 6f 6e 20 2d 2d 0a 20 2a 0a 20 2a 09 20 43  tion --. *. *. C
4a30: 61 6c 63 75 6c 61 74 65 20 6d 65 73 73 61 67 65  alculate message
4a40: 20 64 69 67 65 73 74 20 75 73 69 6e 67 20 68 61   digest using ha
4a50: 73 68 20 66 75 6e 63 74 69 6f 6e 2e 0a 20 2a 0a  sh function.. *.
4a60: 20 2a 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09 54   * Returns:. *.T
4a70: 43 4c 5f 4f 4b 20 6f 72 20 54 43 4c 5f 45 52 52  CL_OK or TCL_ERR
4a80: 4f 52 0a 20 2a 0a 20 2a 20 53 69 64 65 20 65 66  OR. *. * Side ef
4a90: 66 65 63 74 73 3a 0a 20 2a 09 53 65 74 73 20 72  fects:. *.Sets r
4aa0: 65 73 75 6c 74 20 74 6f 20 6d 65 73 73 61 67 65  esult to message
4ab0: 20 64 69 67 65 73 74 20 6f 72 20 65 72 72 6f 72   digest or error
4ac0: 20 6d 65 73 73 61 67 65 0a 20 2a 0a 20 2a 2d 2d   message. *. *--
4ad0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4ae0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4af0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4b00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4b10: 2d 0a 20 2a 2f 0a 69 6e 74 0a 44 69 67 65 73 74  -. */.int.Digest
4b20: 48 61 73 68 46 75 6e 63 74 69 6f 6e 28 54 63 6c  HashFunction(Tcl
4b30: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
4b40: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
4b50: 62 6a 20 2a 63 6f 6e 73 74 20 6f 62 6a 76 5b 5d  bj *const objv[]
4b60: 2c 0a 09 63 6f 6e 73 74 20 45 56 50 5f 4d 44 20  ,..const EVP_MD 
4b70: 2a 6d 64 2c 20 69 6e 74 20 66 6f 72 6d 61 74 2c  *md, int format,
4b80: 20 54 63 6c 5f 4f 62 6a 20 2a 6b 65 79 4f 62 6a   Tcl_Obj *keyObj
4b90: 29 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 64 61  ) {.    char *da
4ba0: 74 61 3b 0a 20 20 20 20 69 6e 74 20 6c 65 6e 2c  ta;.    int len,
4bb0: 20 72 65 73 3b 0a 20 20 20 20 75 6e 73 69 67 6e   res;.    unsign
4bc0: 65 64 20 69 6e 74 20 6d 64 5f 6c 65 6e 3b 0a 20  ed int md_len;. 
4bd0: 20 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72     unsigned char
4be0: 20 6d 64 5f 62 75 66 5b 45 56 50 5f 4d 41 58 5f   md_buf[EVP_MAX_
4bf0: 4d 44 5f 53 49 5a 45 5d 3b 0a 0a 20 20 20 20 69  MD_SIZE];..    i
4c00: 66 20 28 6f 62 6a 63 20 21 3d 20 32 29 20 7b 0a  f (objc != 2) {.
4c10: 09 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67  .Tcl_WrongNumArg
4c20: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
4c30: 76 2c 20 22 64 61 74 61 22 29 3b 0a 09 72 65 74  v, "data");..ret
4c40: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
4c50: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 47 65 74     }..    /* Get
4c60: 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 64 61 74   data */.    dat
4c70: 61 20 3d 20 54 63 6c 5f 47 65 74 42 79 74 65 41  a = Tcl_GetByteA
4c80: 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76  rrayFromObj(objv
4c90: 5b 31 5d 2c 20 26 6c 65 6e 29 3b 0a 20 20 20 20  [1], &len);.    
4ca0: 69 66 20 28 64 61 74 61 20 3d 3d 20 4e 55 4c 4c  if (data == NULL
4cb0: 20 7c 7c 20 6c 65 6e 20 3d 3d 20 30 29 20 7b 0a   || len == 0) {.
4cc0: 09 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69  .Tcl_SetResult(i
4cd0: 6e 74 65 72 70 2c 20 22 4e 6f 20 64 61 74 61 22  nterp, "No data"
4ce0: 2c 20 4e 55 4c 4c 29 3b 0a 09 72 65 74 75 72 6e  , NULL);..return
4cf0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
4d00: 7d 0a 0a 20 20 20 20 2f 2a 20 43 61 6c 63 75 6c  }..    /* Calcul
4d10: 61 74 65 20 64 69 67 65 73 74 20 62 61 73 65 64  ate digest based
4d20: 20 6f 6e 20 68 61 73 68 20 66 75 6e 63 74 69 6f   on hash functio
4d30: 6e 20 2a 2f 0a 20 20 20 20 69 66 20 28 6b 65 79  n */.    if (key
4d40: 4f 62 6a 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  Obj == NULL) {..
4d50: 72 65 73 20 3d 20 45 56 50 5f 44 69 67 65 73 74  res = EVP_Digest
4d60: 28 64 61 74 61 2c 20 28 73 69 7a 65 5f 74 29 20  (data, (size_t) 
4d70: 6c 65 6e 2c 20 6d 64 5f 62 75 66 2c 20 26 6d 64  len, md_buf, &md
4d80: 5f 6c 65 6e 2c 20 6d 64 2c 20 4e 55 4c 4c 29 3b  _len, md, NULL);
4d90: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09 75  .    } else {..u
4da0: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 6b 65  nsigned char *ke
4db0: 79 2c 20 2a 68 6d 61 63 3b 0a 09 69 6e 74 20 6b  y, *hmac;..int k
4dc0: 65 79 5f 6c 65 6e 3b 0a 0a 09 6b 65 79 20 3d 20  ey_len;...key = 
4dd0: 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61 79  Tcl_GetByteArray
4de0: 46 72 6f 6d 4f 62 6a 28 6b 65 79 4f 62 6a 2c 20  FromObj(keyObj, 
4df0: 26 6b 65 79 5f 6c 65 6e 29 3b 0a 09 68 6d 61 63  &key_len);..hmac
4e00: 20 3d 20 48 4d 41 43 28 6d 64 2c 20 28 63 6f 6e   = HMAC(md, (con
4e10: 73 74 20 76 6f 69 64 20 2a 29 20 6b 65 79 2c 20  st void *) key, 
4e20: 6b 65 79 5f 6c 65 6e 2c 20 28 63 6f 6e 73 74 20  key_len, (const 
4e30: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
4e40: 20 64 61 74 61 2c 0a 09 20 20 20 20 28 73 69 7a   data,..    (siz
4e50: 65 5f 74 29 20 6c 65 6e 2c 20 6d 64 5f 62 75 66  e_t) len, md_buf
4e60: 2c 20 26 6d 64 5f 6c 65 6e 29 3b 0a 09 72 65 73  , &md_len);..res
4e70: 20 3d 20 28 68 6d 61 63 20 21 3d 20 4e 55 4c 4c   = (hmac != NULL
4e80: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
4e90: 20 4f 75 74 70 75 74 20 64 69 67 65 73 74 20 74   Output digest t
4ea0: 6f 20 72 65 73 75 6c 74 20 70 65 72 20 66 6f 72  o result per for
4eb0: 6d 61 74 20 28 62 69 6e 20 6f 72 20 68 65 78 29  mat (bin or hex)
4ec0: 20 2a 2f 0a 20 20 20 20 69 66 20 28 72 65 73 29   */.    if (res)
4ed0: 20 7b 0a 09 69 66 20 28 66 6f 72 6d 61 74 20 3d   {..if (format =
4ee0: 3d 20 42 49 4e 5f 46 4f 52 4d 41 54 29 20 7b 0a  = BIN_FORMAT) {.
4ef0: 09 20 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52  .    Tcl_SetObjR
4f00: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63  esult(interp, Tc
4f10: 6c 5f 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62  l_NewByteArrayOb
4f20: 6a 28 6d 64 5f 62 75 66 2c 20 6d 64 5f 6c 65 6e  j(md_buf, md_len
4f30: 29 29 3b 0a 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  ));...} else {..
4f40: 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 72 65 73      Tcl_Obj *res
4f50: 75 6c 74 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77  ultObj = Tcl_New
4f60: 4f 62 6a 28 29 3b 0a 09 20 20 20 20 75 6e 73 69  Obj();..    unsi
4f70: 67 6e 65 64 20 63 68 61 72 20 2a 70 74 72 20 3d  gned char *ptr =
4f80: 20 54 63 6c 5f 53 65 74 42 79 74 65 41 72 72 61   Tcl_SetByteArra
4f90: 79 4c 65 6e 67 74 68 28 72 65 73 75 6c 74 4f 62  yLength(resultOb
4fa0: 6a 2c 20 6d 64 5f 6c 65 6e 2a 32 29 3b 0a 0a 09  j, md_len*2);...
4fb0: 20 20 20 20 66 6f 72 20 28 75 6e 73 69 67 6e 65      for (unsigne
4fc0: 64 20 69 6e 74 20 69 20 3d 20 30 3b 20 69 20 3c  d int i = 0; i <
4fd0: 20 6d 64 5f 6c 65 6e 3b 20 69 2b 2b 29 20 7b 0a   md_len; i++) {.
4fe0: 09 09 2a 70 74 72 2b 2b 20 3d 20 68 65 78 5b 28  ..*ptr++ = hex[(
4ff0: 6d 64 5f 62 75 66 5b 69 5d 20 3e 3e 20 34 29 20  md_buf[i] >> 4) 
5000: 26 20 30 78 30 46 5d 3b 0a 09 09 2a 70 74 72 2b  & 0x0F];...*ptr+
5010: 2b 20 3d 20 68 65 78 5b 6d 64 5f 62 75 66 5b 69  + = hex[md_buf[i
5020: 5d 20 26 20 30 78 30 46 5d 3b 0a 09 20 20 20 20  ] & 0x0F];..    
5030: 7d 0a 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  }..Tcl_SetObjRes
5040: 75 6c 74 28 69 6e 74 65 72 70 2c 20 72 65 73 75  ult(interp, resu
5050: 6c 74 4f 62 6a 29 3b 0a 09 7d 0a 0a 20 20 20 20  ltObj);..}..    
5060: 7d 20 65 6c 73 65 20 7b 0a 09 54 63 6c 5f 41 70  } else {..Tcl_Ap
5070: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
5080: 70 2c 20 22 48 61 73 68 20 63 61 6c 63 75 6c 61  p, "Hash calcula
5090: 74 69 6f 6e 20 65 72 72 6f 72 3a 22 2c 20 52 45  tion error:", RE
50a0: 41 53 4f 4e 28 29 2c 20 28 63 68 61 72 20 2a 29  ASON(), (char *)
50b0: 20 4e 55 4c 4c 29 3b 0a 09 72 65 74 75 72 6e 20   NULL);..return 
50c0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  TCL_ERROR;.    }
50d0: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
50e0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d  OK;.}../*. *----
50f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5100: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5110: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5120: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
5130: 20 2a 0a 20 2a 20 44 69 67 65 73 74 4f 62 6a 43   *. * DigestObjC
5140: 6d 64 20 2d 2d 0a 20 2a 0a 20 2a 09 52 65 74 75  md --. *. *.Retu
5150: 72 6e 20 6d 65 73 73 61 67 65 20 64 69 67 65 73  rn message diges
5160: 74 20 75 73 69 6e 67 20 75 73 65 72 20 73 70 65  t using user spe
5170: 63 69 66 69 65 64 20 68 61 73 68 20 66 75 6e 63  cified hash func
5180: 74 69 6f 6e 2e 0a 20 2a 0a 20 2a 20 52 65 74 75  tion.. *. * Retu
5190: 72 6e 73 3a 0a 20 2a 09 54 43 4c 5f 4f 4b 20 6f  rns:. *.TCL_OK o
51a0: 72 20 54 43 4c 5f 45 52 52 4f 52 0a 20 2a 0a 20  r TCL_ERROR. *. 
51b0: 2a 20 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a  * Side effects:.
51c0: 20 2a 09 53 65 74 73 20 72 65 73 75 6c 74 20 74   *.Sets result t
51d0: 6f 20 6d 65 73 73 61 67 65 20 64 69 67 65 73 74  o message digest
51e0: 20 6f 72 20 65 72 72 6f 72 20 6d 65 73 73 61 67   or error messag
51f0: 65 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d  e. *. *---------
5200: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 73  ----------. */.s
5240: 74 61 74 69 63 20 69 6e 74 0a 44 69 67 65 73 74  tatic int.Digest
5250: 4f 62 6a 43 6d 64 28 43 6c 69 65 6e 74 44 61 74  ObjCmd(ClientDat
5260: 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 54 63  a clientData, Tc
5270: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5280: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
5290: 4f 62 6a 20 2a 63 6f 6e 73 74 20 6f 62 6a 76 5b  Obj *const objv[
52a0: 5d 29 20 7b 0a 20 20 20 20 69 6e 74 20 69 64 78  ]) {.    int idx
52b0: 2c 20 6c 65 6e 2c 20 66 6f 72 6d 61 74 20 3d 20  , len, format = 
52c0: 48 45 58 5f 46 4f 52 4d 41 54 2c 20 6b 65 79 5f  HEX_FORMAT, key_
52d0: 6c 65 6e 20 3d 20 30 2c 20 64 61 74 61 5f 6c 65  len = 0, data_le
52e0: 6e 20 3d 20 30 3b 0a 20 20 20 20 63 6f 6e 73 74  n = 0;.    const
52f0: 20 63 68 61 72 20 2a 64 69 67 65 73 74 6e 61 6d   char *digestnam
5300: 65 2c 20 2a 63 68 61 6e 6e 65 6c 20 3d 20 4e 55  e, *channel = NU
5310: 4c 4c 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20  LL;.    Tcl_Obj 
5320: 2a 64 61 74 61 4f 62 6a 20 3d 20 4e 55 4c 4c 2c  *dataObj = NULL,
5330: 20 2a 66 69 6c 65 4f 62 6a 20 3d 20 4e 55 4c 4c   *fileObj = NULL
5340: 2c 20 2a 6b 65 79 4f 62 6a 20 3d 20 4e 55 4c 4c  , *keyObj = NULL
5350: 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 63  ;.    unsigned c
5360: 68 61 72 20 2a 6b 65 79 20 3d 20 4e 55 4c 4c 3b  har *key = NULL;
5370: 0a 20 20 20 20 63 6f 6e 73 74 20 45 56 50 5f 4d  .    const EVP_M
5380: 44 20 2a 6d 64 3b 0a 0a 20 20 20 20 54 63 6c 5f  D *md;..    Tcl_
5390: 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65  ResetResult(inte
53a0: 72 70 29 3b 0a 0a 20 20 20 20 69 66 20 28 6f 62  rp);..    if (ob
53b0: 6a 63 20 3c 20 33 20 7c 7c 20 6f 62 6a 63 20 3e  jc < 3 || objc >
53c0: 20 37 29 20 7b 0a 09 54 63 6c 5f 57 72 6f 6e 67   7) {..Tcl_Wrong
53d0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
53e0: 31 2c 20 6f 62 6a 76 2c 20 22 74 79 70 65 20 3f  1, objv, "type ?
53f0: 2d 62 69 6e 7c 2d 68 65 78 3f 20 3f 2d 6b 65 79  -bin|-hex? ?-key
5400: 20 68 6d 61 63 5f 6b 65 79 3f 20 5b 2d 63 68 61   hmac_key? [-cha
5410: 6e 6e 65 6c 20 63 68 61 6e 20 7c 20 2d 66 69 6c  nnel chan | -fil
5420: 65 20 66 69 6c 65 6e 61 6d 65 20 7c 20 3f 2d 64  e filename | ?-d
5430: 61 74 61 3f 20 64 61 74 61 5d 22 29 3b 0a 09 72  ata? data]");..r
5440: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
5450: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 47  .    }..    /* G
5460: 65 74 20 64 69 67 65 73 74 20 2a 2f 0a 20 20 20  et digest */.   
5470: 20 64 69 67 65 73 74 6e 61 6d 65 20 3d 20 54 63   digestname = Tc
5480: 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f  l_GetStringFromO
5490: 62 6a 28 6f 62 6a 76 5b 31 5d 2c 20 26 6c 65 6e  bj(objv[1], &len
54a0: 29 3b 0a 20 20 20 20 69 66 20 28 64 69 67 65 73  );.    if (diges
54b0: 74 6e 61 6d 65 20 3d 3d 20 4e 55 4c 4c 20 7c 7c  tname == NULL ||
54c0: 20 28 6d 64 20 3d 20 45 56 50 5f 67 65 74 5f 64   (md = EVP_get_d
54d0: 69 67 65 73 74 62 79 6e 61 6d 65 28 64 69 67 65  igestbyname(dige
54e0: 73 74 6e 61 6d 65 29 29 20 3d 3d 20 4e 55 4c 4c  stname)) == NULL
54f0: 29 20 7b 0a 09 54 63 6c 5f 41 70 70 65 6e 64 52  ) {..Tcl_AppendR
5500: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 49  esult(interp, "I
5510: 6e 76 61 6c 69 64 20 64 69 67 65 73 74 20 74 79  nvalid digest ty
5520: 70 65 20 5c 22 22 2c 20 64 69 67 65 73 74 6e 61  pe \"", digestna
5530: 6d 65 2c 20 22 5c 22 22 2c 20 4e 55 4c 4c 29 3b  me, "\"", NULL);
5540: 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52  ..return TCL_ERR
5550: 4f 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  OR;.    }..    /
5560: 2a 20 4f 70 74 69 6d 61 6c 20 63 61 73 65 20 66  * Optimal case f
5570: 6f 72 20 62 6c 6f 62 20 6f 66 20 64 61 74 61 20  or blob of data 
5580: 2a 2f 0a 20 20 20 20 69 66 20 28 6f 62 6a 63 20  */.    if (objc 
5590: 3d 3d 20 33 29 20 7b 0a 09 72 65 74 75 72 6e 20  == 3) {..return 
55a0: 44 69 67 65 73 74 48 61 73 68 46 75 6e 63 74 69  DigestHashFuncti
55b0: 6f 6e 28 69 6e 74 65 72 70 2c 20 2d 2d 6f 62 6a  on(interp, --obj
55c0: 63 2c 20 2b 2b 6f 62 6a 76 2c 20 6d 64 2c 20 66  c, ++objv, md, f
55d0: 6f 72 6d 61 74 2c 20 4e 55 4c 4c 29 3b 0a 20 20  ormat, NULL);.  
55e0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 47 65 74 20    }..    /* Get 
55f0: 6f 70 74 69 6f 6e 73 20 2a 2f 0a 20 20 20 20 66  options */.    f
5600: 6f 72 20 28 69 64 78 20 3d 20 32 3b 20 69 64 78  or (idx = 2; idx
5610: 20 3c 20 6f 62 6a 63 2d 31 3b 20 69 64 78 2b 2b   < objc-1; idx++
5620: 29 20 7b 0a 09 63 68 61 72 20 2a 6f 70 74 20 3d  ) {..char *opt =
5630: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72   Tcl_GetStringFr
5640: 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 69 64 78 5d 2c  omObj(objv[idx],
5650: 20 4e 55 4c 4c 29 3b 0a 0a 09 69 66 20 28 6f 70   NULL);...if (op
5660: 74 5b 30 5d 20 21 3d 20 27 2d 27 29 0a 09 20 20  t[0] != '-')..  
5670: 20 20 62 72 65 61 6b 3b 0a 0a 09 4f 50 54 46 4c    break;...OPTFL
5680: 41 47 28 22 2d 62 69 6e 22 2c 20 66 6f 72 6d 61  AG("-bin", forma
5690: 74 2c 20 42 49 4e 5f 46 4f 52 4d 41 54 29 3b 0a  t, BIN_FORMAT);.
56a0: 09 4f 50 54 46 4c 41 47 28 22 2d 62 69 6e 61 72  .OPTFLAG("-binar
56b0: 79 22 2c 20 66 6f 72 6d 61 74 2c 20 42 49 4e 5f  y", format, BIN_
56c0: 46 4f 52 4d 41 54 29 3b 0a 09 4f 50 54 46 4c 41  FORMAT);..OPTFLA
56d0: 47 28 22 2d 68 65 78 22 2c 20 66 6f 72 6d 61 74  G("-hex", format
56e0: 2c 20 48 45 58 5f 46 4f 52 4d 41 54 29 3b 0a 09  , HEX_FORMAT);..
56f0: 4f 50 54 46 4c 41 47 28 22 2d 68 65 78 61 64 65  OPTFLAG("-hexade
5700: 63 69 6d 61 6c 22 2c 20 66 6f 72 6d 61 74 2c 20  cimal", format, 
5710: 48 45 58 5f 46 4f 52 4d 41 54 29 3b 0a 09 4f 50  HEX_FORMAT);..OP
5720: 54 4f 42 4a 28 22 2d 64 61 74 61 22 2c 20 64 61  TOBJ("-data", da
5730: 74 61 4f 62 6a 29 3b 0a 09 4f 50 54 53 54 52 28  taObj);..OPTSTR(
5740: 22 2d 63 68 61 6e 22 2c 20 63 68 61 6e 6e 65 6c  "-chan", channel
5750: 29 3b 0a 09 4f 50 54 53 54 52 28 22 2d 63 68 61  );..OPTSTR("-cha
5760: 6e 6e 65 6c 22 2c 20 63 68 61 6e 6e 65 6c 29 3b  nnel", channel);
5770: 0a 09 4f 50 54 4f 42 4a 28 22 2d 66 69 6c 65 22  ..OPTOBJ("-file"
5780: 2c 20 66 69 6c 65 4f 62 6a 29 3b 0a 09 4f 50 54  , fileObj);..OPT
5790: 4f 42 4a 28 22 2d 66 69 6c 65 6e 61 6d 65 22 2c  OBJ("-filename",
57a0: 20 66 69 6c 65 4f 62 6a 29 3b 0a 09 4f 50 54 4f   fileObj);..OPTO
57b0: 42 4a 28 22 2d 6b 65 79 22 2c 20 6b 65 79 4f 62  BJ("-key", keyOb
57c0: 6a 29 3b 0a 0a 09 4f 50 54 42 41 44 28 22 6f 70  j);...OPTBAD("op
57d0: 74 69 6f 6e 22 2c 20 22 2d 62 69 6e 2c 20 2d 64  tion", "-bin, -d
57e0: 61 74 61 2c 20 2d 66 69 6c 65 2c 20 2d 66 69 6c  ata, -file, -fil
57f0: 65 6e 61 6d 65 2c 20 2d 68 65 78 2c 20 6f 72 20  ename, -hex, or 
5800: 2d 6b 65 79 22 29 3b 0a 09 72 65 74 75 72 6e 20  -key");..return 
5810: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  TCL_ERROR;.    }
5820: 0a 0a 20 20 20 20 2f 2a 20 49 66 20 6e 6f 20 6f  ..    /* If no o
5830: 70 74 69 6f 6e 20 66 6f 72 20 6c 61 73 74 20 61  ption for last a
5840: 72 67 2c 20 74 68 65 6e 20 69 74 73 20 74 68 65  rg, then its the
5850: 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 69 66 20   data */.    if 
5860: 28 69 64 78 20 3c 20 6f 62 6a 63 29 20 7b 0a 09  (idx < objc) {..
5870: 64 61 74 61 4f 62 6a 20 3d 20 6f 62 6a 76 5b 69  dataObj = objv[i
5880: 64 78 5d 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  dx];.    }..    
5890: 2f 2a 20 43 61 6c 63 20 64 69 67 65 73 74 20 6f  /* Calc digest o
58a0: 6e 20 66 69 6c 65 2c 20 73 74 61 63 6b 65 64 20  n file, stacked 
58b0: 63 68 61 6e 6e 65 6c 2c 20 6f 72 20 64 61 74 61  channel, or data
58c0: 20 62 6c 6f 62 20 2a 2f 0a 20 20 20 20 69 66 20   blob */.    if 
58d0: 28 66 69 6c 65 4f 62 6a 20 21 3d 20 4e 55 4c 4c  (fileObj != NULL
58e0: 29 20 7b 0a 09 72 65 74 75 72 6e 20 44 69 67 65  ) {..return Dige
58f0: 73 74 46 69 6c 65 28 69 6e 74 65 72 70 2c 20 66  stFile(interp, f
5900: 69 6c 65 4f 62 6a 2c 20 6d 64 2c 20 66 6f 72 6d  ileObj, md, form
5910: 61 74 2c 20 6b 65 79 4f 62 6a 29 3b 0a 20 20 20  at, keyObj);.   
5920: 20 7d 20 65 6c 73 65 20 69 66 20 28 63 68 61 6e   } else if (chan
5930: 6e 65 6c 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  nel != NULL) {..
5940: 72 65 74 75 72 6e 20 44 69 67 65 73 74 43 68 61  return DigestCha
5950: 6e 6e 65 6c 28 69 6e 74 65 72 70 2c 20 63 68 61  nnel(interp, cha
5960: 6e 6e 65 6c 2c 20 6d 64 2c 20 66 6f 72 6d 61 74  nnel, md, format
5970: 29 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 69 66  );.    } else if
5980: 20 28 64 61 74 61 4f 62 6a 20 21 3d 20 4e 55 4c   (dataObj != NUL
5990: 4c 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 6f  L) {..Tcl_Obj *o
59a0: 62 6a 73 5b 32 5d 3b 0a 09 6f 62 6a 73 5b 30 5d  bjs[2];..objs[0]
59b0: 20 3d 20 4e 55 4c 4c 3b 0a 09 6f 62 6a 73 5b 31   = NULL;..objs[1
59c0: 5d 20 3d 20 64 61 74 61 4f 62 6a 3b 0a 09 72 65  ] = dataObj;..re
59d0: 74 75 72 6e 20 44 69 67 65 73 74 48 61 73 68 46  turn DigestHashF
59e0: 75 6e 63 74 69 6f 6e 28 69 6e 74 65 72 70 2c 20  unction(interp, 
59f0: 32 2c 20 6f 62 6a 73 2c 20 6d 64 2c 20 66 6f 72  2, objs, md, for
5a00: 6d 61 74 2c 20 6b 65 79 4f 62 6a 29 3b 0a 20 20  mat, keyObj);.  
5a10: 20 20 7d 0a 0a 20 20 20 20 54 63 6c 5f 41 70 70    }..    Tcl_App
5a20: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
5a30: 2c 20 22 4e 6f 20 64 61 74 61 20 73 70 65 63 69  , "No data speci
5a40: 66 69 65 64 2e 22 2c 20 4e 55 4c 4c 29 3b 0a 20  fied.", NULL);. 
5a50: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
5a60: 52 4f 52 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d  ROR;.}../*. *---
5a70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5a90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5aa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5ab0: 0a 20 2a 0a 20 2a 20 4d 65 73 73 61 67 65 20 44  . *. * Message D
5ac0: 69 67 65 73 74 20 43 6f 6e 76 65 6e 69 65 6e 63  igest Convenienc
5ad0: 65 20 43 6f 6d 6d 61 6e 64 73 20 2d 2d 0a 20 2a  e Commands --. *
5ae0: 0a 20 2a 09 43 6f 6e 76 65 6e 69 65 6e 63 65 20  . *.Convenience 
5af0: 63 6f 6d 6d 61 6e 64 73 20 66 6f 72 20 6d 65 73  commands for mes
5b00: 73 61 67 65 20 64 69 67 65 73 74 73 2e 0a 20 2a  sage digests.. *
5b10: 0a 20 2a 20 52 65 74 75 72 6e 73 3a 0a 20 2a 09  . * Returns:. *.
5b20: 54 43 4c 5f 4f 4b 20 6f 72 20 54 43 4c 5f 45 52  TCL_OK or TCL_ER
5b30: 52 4f 52 0a 20 2a 0a 20 2a 20 53 69 64 65 20 65  ROR. *. * Side e
5b40: 66 66 65 63 74 73 3a 0a 20 2a 09 53 65 74 73 20  ffects:. *.Sets 
5b50: 72 65 73 75 6c 74 20 74 6f 20 6d 65 73 73 61 67  result to messag
5b60: 65 20 64 69 67 65 73 74 20 6f 72 20 65 72 72 6f  e digest or erro
5b70: 72 20 6d 65 73 73 61 67 65 0a 20 2a 0a 20 2a 2d  r message. *. *-
5b80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5b90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5ba0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5bb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5bc0: 2d 2d 0a 20 2a 2f 0a 69 6e 74 20 44 69 67 65 73  --. */.int Diges
5bd0: 74 4d 44 34 43 6d 64 28 43 6c 69 65 6e 74 44 61  tMD4Cmd(ClientDa
5be0: 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 54  ta clientData, T
5bf0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
5c00: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
5c10: 5f 4f 62 6a 20 2a 63 6f 6e 73 74 20 6f 62 6a 76  _Obj *const objv
5c20: 5b 5d 29 20 7b 0a 20 20 20 20 72 65 74 75 72 6e  []) {.    return
5c30: 20 44 69 67 65 73 74 48 61 73 68 46 75 6e 63 74   DigestHashFunct
5c40: 69 6f 6e 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63  ion(interp, objc
5c50: 2c 20 6f 62 6a 76 2c 20 45 56 50 5f 6d 64 34 28  , objv, EVP_md4(
5c60: 29 2c 20 48 45 58 5f 46 4f 52 4d 41 54 2c 20 4e  ), HEX_FORMAT, N
5c70: 55 4c 4c 29 3b 0a 7d 0a 0a 69 6e 74 20 44 69 67  ULL);.}..int Dig
5c80: 65 73 74 4d 44 35 43 6d 64 28 43 6c 69 65 6e 74  estMD5Cmd(Client
5c90: 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c  Data clientData,
5ca0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
5cb0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
5cc0: 63 6c 5f 4f 62 6a 20 2a 63 6f 6e 73 74 20 6f 62  cl_Obj *const ob
5cd0: 6a 76 5b 5d 29 20 7b 0a 20 20 20 20 72 65 74 75  jv[]) {.    retu
5ce0: 72 6e 20 44 69 67 65 73 74 48 61 73 68 46 75 6e  rn DigestHashFun
5cf0: 63 74 69 6f 6e 28 69 6e 74 65 72 70 2c 20 6f 62  ction(interp, ob
5d00: 6a 63 2c 20 6f 62 6a 76 2c 20 45 56 50 5f 6d 64  jc, objv, EVP_md
5d10: 35 28 29 2c 20 48 45 58 5f 46 4f 52 4d 41 54 2c  5(), HEX_FORMAT,
5d20: 20 4e 55 4c 4c 29 3b 0a 7d 0a 0a 69 6e 74 20 44   NULL);.}..int D
5d30: 69 67 65 73 74 53 48 41 31 43 6d 64 28 43 6c 69  igestSHA1Cmd(Cli
5d40: 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61  entData clientDa
5d50: 74 61 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ta, Tcl_Interp *
5d60: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
5d70: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 63 6f 6e 73 74  , Tcl_Obj *const
5d80: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 20 20 20 20 72   objv[]) {.    r
5d90: 65 74 75 72 6e 20 44 69 67 65 73 74 48 61 73 68  eturn DigestHash
5da0: 46 75 6e 63 74 69 6f 6e 28 69 6e 74 65 72 70 2c  Function(interp,
5db0: 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20 45 56 50   objc, objv, EVP
5dc0: 5f 73 68 61 31 28 29 2c 20 48 45 58 5f 46 4f 52  _sha1(), HEX_FOR
5dd0: 4d 41 54 2c 20 4e 55 4c 4c 29 3b 0a 7d 0a 0a 69  MAT, NULL);.}..i
5de0: 6e 74 20 44 69 67 65 73 74 53 48 41 32 35 36 43  nt DigestSHA256C
5df0: 6d 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 6c  md(ClientData cl
5e00: 69 65 6e 74 44 61 74 61 2c 20 54 63 6c 5f 49 6e  ientData, Tcl_In
5e10: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
5e20: 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20  t objc, Tcl_Obj 
5e30: 2a 63 6f 6e 73 74 20 6f 62 6a 76 5b 5d 29 20 7b  *const objv[]) {
5e40: 0a 20 20 20 20 72 65 74 75 72 6e 20 44 69 67 65  .    return Dige
5e50: 73 74 48 61 73 68 46 75 6e 63 74 69 6f 6e 28 69  stHashFunction(i
5e60: 6e 74 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a  nterp, objc, obj
5e70: 76 2c 20 45 56 50 5f 73 68 61 32 35 36 28 29 2c  v, EVP_sha256(),
5e80: 20 48 45 58 5f 46 4f 52 4d 41 54 2c 20 4e 55 4c   HEX_FORMAT, NUL
5e90: 4c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d  L);.}../*. *----
5ea0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5eb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5ec0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5ed0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
5ee0: 20 2a 0a 20 2a 20 54 6c 73 5f 44 69 67 65 73 74   *. * Tls_Digest
5ef0: 43 6f 6d 6d 61 6e 64 73 20 2d 2d 0a 20 2a 0a 20  Commands --. *. 
5f00: 2a 09 43 72 65 61 74 65 20 64 69 67 65 73 74 20  *.Create digest 
5f10: 63 6f 6d 6d 61 6e 64 73 0a 20 2a 0a 20 2a 20 52  commands. *. * R
5f20: 65 74 75 72 6e 73 3a 0a 20 2a 09 54 43 4c 5f 4f  eturns:. *.TCL_O
5f30: 4b 20 6f 72 20 54 43 4c 5f 45 52 52 4f 52 0a 20  K or TCL_ERROR. 
5f40: 2a 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74  *. * Side effect
5f50: 73 3a 0a 20 2a 09 43 72 65 61 74 65 73 20 63 6f  s:. *.Creates co
5f60: 6d 6d 61 6e 64 73 0a 20 2a 0a 20 2a 2d 2d 2d 2d  mmands. *. *----
5f70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5f80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5f90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5fa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
5fb0: 20 2a 2f 0a 69 6e 74 20 54 6c 73 5f 44 69 67 65   */.int Tls_Dige
5fc0: 73 74 43 6f 6d 6d 61 6e 64 73 28 54 63 6c 5f 49  stCommands(Tcl_I
5fd0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b  nterp *interp) {
5fe0: 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  .    Tcl_CreateO
5ff0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
6000: 2c 20 22 74 6c 73 3a 3a 64 69 67 65 73 74 22 2c  , "tls::digest",
6010: 20 44 69 67 65 73 74 4f 62 6a 43 6d 64 2c 20 28   DigestObjCmd, (
6020: 43 6c 69 65 6e 74 44 61 74 61 29 20 30 2c 20 28  ClientData) 0, (
6030: 54 63 6c 5f 43 6d 64 44 65 6c 65 74 65 50 72 6f  Tcl_CmdDeletePro
6040: 63 20 2a 29 20 4e 55 4c 4c 29 3b 0a 20 20 20 20  c *) NULL);.    
6050: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
6060: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 74 6c  mand(interp, "tl
6070: 73 3a 3a 6d 64 34 22 2c 20 44 69 67 65 73 74 4d  s::md4", DigestM
6080: 44 34 43 6d 64 2c 20 28 43 6c 69 65 6e 74 44 61  D4Cmd, (ClientDa
6090: 74 61 29 20 30 2c 20 28 54 63 6c 5f 43 6d 64 44  ta) 0, (Tcl_CmdD
60a0: 65 6c 65 74 65 50 72 6f 63 20 2a 29 20 4e 55 4c  eleteProc *) NUL
60b0: 4c 29 3b 0a 20 20 20 20 54 63 6c 5f 43 72 65 61  L);.    Tcl_Crea
60c0: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
60d0: 65 72 70 2c 20 22 74 6c 73 3a 3a 6d 64 35 22 2c  erp, "tls::md5",
60e0: 20 44 69 67 65 73 74 4d 44 35 43 6d 64 2c 20 28   DigestMD5Cmd, (
60f0: 43 6c 69 65 6e 74 44 61 74 61 29 20 30 2c 20 28  ClientData) 0, (
6100: 54 63 6c 5f 43 6d 64 44 65 6c 65 74 65 50 72 6f  Tcl_CmdDeletePro
6110: 63 20 2a 29 20 4e 55 4c 4c 29 3b 0a 20 20 20 20  c *) NULL);.    
6120: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
6130: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 74 6c  mand(interp, "tl
6140: 73 3a 3a 73 68 61 31 22 2c 20 44 69 67 65 73 74  s::sha1", Digest
6150: 53 48 41 31 43 6d 64 2c 20 28 43 6c 69 65 6e 74  SHA1Cmd, (Client
6160: 44 61 74 61 29 20 30 2c 20 28 54 63 6c 5f 43 6d  Data) 0, (Tcl_Cm
6170: 64 44 65 6c 65 74 65 50 72 6f 63 20 2a 29 20 4e  dDeleteProc *) N
6180: 55 4c 4c 29 3b 0a 20 20 20 20 54 63 6c 5f 43 72  ULL);.    Tcl_Cr
6190: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
61a0: 6e 74 65 72 70 2c 20 22 74 6c 73 3a 3a 73 68 61  nterp, "tls::sha
61b0: 32 35 36 22 2c 20 44 69 67 65 73 74 53 48 41 32  256", DigestSHA2
61c0: 35 36 43 6d 64 2c 20 28 43 6c 69 65 6e 74 44 61  56Cmd, (ClientDa
61d0: 74 61 29 20 30 2c 20 28 54 63 6c 5f 43 6d 64 44  ta) 0, (Tcl_CmdD
61e0: 65 6c 65 74 65 50 72 6f 63 20 2a 29 20 4e 55 4c  eleteProc *) NUL
61f0: 4c 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  L);.    return T
6200: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a                    CL_OK;.}..