pike.git / lib / modules / Crypto.pmod / PGP.pmod

version» Context lines:

pike.git/lib/modules/Crypto.pmod/PGP.pmod:1:    - //! PGP stuff. See RFC 4880. + //! PGP stuff. See @rfc{4880@}.      #pike __REAL_VERSION__ -  + #require constant(Crypto.HashState)    - #if constant(Crypto.HashState) + protected Gmp.mpz read_number(Stdio.Buffer b) + { +  int bits = b->read_int(2); +  return Gmp.mpz(b->read_int( (bits+7)>>3 )); + }      // Decodes a PGP public key.   // @returns   // @mapping   // @member int version   // @member int tstamp   // @member int validity   // @member object key   // @endmapping - protected mapping decode_public_key(string s) { -  + protected mapping decode_public_key(Stdio.Buffer b) + {    mapping r = ([]); -  string key; -  int l; -  if(s[0]>=4) -  sscanf(s, "%1c%4c%1c%2c%s", r->version, r->tstamp, -  r->type, l, key); -  else -  sscanf(s, "%1c%4c%2c%1c%2c%s", r->version, r->tstamp, r->validity, -  r->type, l, key); +     -  +  r->version = b->read_int8(); +  r->tstamp = b->read_int32(); +  if( r->version < 4 ) +  r->validity = b->read16(); +  r->type = b->read_int8(); +     switch(r->type) {    case 1: {    // RSA, Encrypt or Sign    r->_type = "RSA (encrypt or sign)"; -  Gmp.mpz n, e; +     -  l = (l+7)>>3; -  n = Gmp.mpz(key[..l-1],256); -  sscanf(key[l..], "%2c%s", l, key); -  l = (l+7)>>3; -  e = Gmp.mpz(key[..l-1],256); -  r->key = Crypto.RSA()->set_public_key(n, e); +  // n and e +  r->key = Crypto.RSA()->set_public_key(read_number(b), read_number(b));    }    break;    case 2:    // RSA, Encrypt only    r->_type = "RSA (encrypt only)";    break;    case 3:    // RSA, Sign only    r->_type = "RSA (sign only)";    break;    case 16:    // Elgamal, Encrypt only    r->_type = "Elgamal (encrypt only)";    break;    case 17: {    // DSA    r->_type = "DSA"; -  Gmp.mpz p, q, g, y; +     -  l = (l+7)>>3; -  p = Gmp.mpz(key[..l-1],256); -  sscanf(key[l..], "%2c%s", l, key); -  l = (l+7)>>3; -  q = Gmp.mpz(key[..l-1],256); -  sscanf(key[l..], "%2c%s", l, key); -  l = (l+7)>>3; -  g = Gmp.mpz(key[..l-1],256); -  sscanf(key[l..], "%2c%s", l, key); -  l = (l+7)>>3; -  y = Gmp.mpz(key[..l-1],256); -  r->key = Crypto.DSA()->set_public_key(p, q, g, y); -  r->key->random = Crypto.Random.random_string; +  // p, q, g and y +  r->key = Crypto.DSA()->set_public_key(read_number(b), read_number(b), +  read_number(b), read_number(b));    }    break;    case 18:    // Elliptic Curve    r->_rtype = "ECC";    break;    case 19:    // ECDSA    r->_type = "ECDSA";    break;
pike.git/lib/modules/Crypto.pmod/PGP.pmod:92: Inside #if constant(Crypto.HashState)
   r->type = "Private/experimental";    break;    default:    r->_type = "Unknown";    break;    }       return r;   }    + protected mapping decode_secret_key(Stdio.Buffer b) + { +  mapping r = decode_public_key(b); +  +  int usage = b->read_int8(); +  if( usage != 0 ) +  { +  r->_error = "Only unencrypted string-to-key usage supported."; +  return r; +  } +  +  switch(r->type) +  { +  case 1: +  // d, p and q. +  r->key->set_private_key(read_number(b), ({ read_number(b), read_number(b) })); +  // u. Not used +  read_number(b); +  break; +  +  case 17: +  // x +  r->key->set_private_key(read_number(b)); +  break; +  } +  +  return r; + } +    // Decodes a PGP signature   // @returns   // @mapping   // @member int version   // @member int classification   // @member int tstamp   // @member string key_id   // @member int type   // @member int digest_algorithm   // @member int md_csum   //   // @member Gmp.mpz digest   //   // @member Gmp.mpz digest_r   // @member Gmp.mpz digest_s   // @endmapping - protected mapping decode_signature(string s) { -  + protected mapping decode_signature(Stdio.Buffer b) + {    mapping r = ([]); -  int l5, l; -  string dig; -  sscanf(s, "%1c%1c%1c%4c%8s%1c%1c%2c%2c%s", r->version, l5, r->classification, -  r->tstamp, r->key_id, r->type, r->digest_algorithm, -  r->md_csum, l, dig); +  r->version = b->read_int8(); +  int l5 = b->read_int8(); +  r->classification = b->read_int8(); +  r->tstamp = b->read_int32(); +  r->key_id = b->read(8); +  r->type = b->read_int8(); +  r->digest_algorithm = b->read_int8(); +  r->md_csum = b->read_int16(); +     if(r->type == 1) { -  l = (l+7)>>3; -  r->digest = Gmp.mpz(dig[..l-1],256); +  r->digest = read_number(b);    } else if(r->type == 17) { -  l = (l+7)>>3; -  r->digest_r = Gmp.mpz(dig[..l-1],256); -  sscanf(dig[l..], "%2c%s", l, dig); -  l = (l+7)>>3; -  r->digest_s = Gmp.mpz(dig[..l-1],256); +  r->digest_r = read_number(b); +  r->digest_s = read_number(b);    }    return r;   }      protected mapping decode_compressed(string s) {    int type = s[0];    s = s[1..];    switch(type) {    case 1:    // ZIP
pike.git/lib/modules/Crypto.pmod/PGP.pmod:176: Inside #if constant(Crypto.HashState)
   0b101101:"user_id",    0b101110:"public_subkey",    0b101111:"user_attribute",    0b110000:"sym_encrypt_and_integrity",    0b110001:"modification_detection",   ]);      protected mapping(string:function) pgp_decoder = ([    "public_key":decode_public_key,    "public_subkey":decode_public_key, +  "secret_key":decode_secret_key, +  "secret_subkey":decode_secret_key,    "signature":decode_signature,    "compressed_data":decode_compressed,   ]);      //! Decodes PGP data. - mapping(string:string|mapping) decode(string s) { + mapping(string:string|mapping|array) decode(string s) + { +  Stdio.Buffer buf = Stdio.Buffer(s); +  mapping(string:string|mapping|array) r = ([]); +  while( sizeof(buf) ) +  { +  int h = buf->read_int8(); +  Stdio.Buffer data; +  if( (h&3) == 3 ) +  { +  data = buf; +  } +  else +  { +  int len = 1<<(h&3); +  data = buf->read_hbuffer( len ); +  if( !data ) +  { +  if( len<=sizeof(buf) ) +  len = buf->read_int(len); +  error("Attempt to read %d from %d bytes of data.\n", len, sizeof(buf)); +  } +  }    -  mapping(string:string|mapping) r = ([]); -  int i = 0; -  while(i<strlen(s)) { -  int h = s[i++]; -  int data_l = 0; -  switch(h&3) { -  case 0: -  sscanf(s[i..i], "%1c", data_l); -  i++; -  break; -  case 1: -  sscanf(s[i..i+1], "%2c", data_l); -  i+=2; -  break; -  case 2: -  sscanf(s[i..i+3], "%4c", data_l); -  i+=4; -  break; -  case 3: -  data_l = strlen(s)-i; -  break; +  h >>= 2; +  string id = pgp_id[h] || sprintf("unknown_%07b",h); +  mapping|string val; +  if(pgp_decoder[id]) +  val = pgp_decoder[id](data); +  else +  val = data->read(); +  +  if( r[id] ) +  { +  if(!arrayp(r[id])) +  r[id] = ({ r[id], val }); +  else +  r[id] += ({ r[id] });    } -  if(i+data_l > strlen(s)) -  error("Bad PGP data\n"); -  h>>=2; -  if(pgp_id[h]) -  r[pgp_id[h]] = (pgp_decoder[pgp_id[h]] || `+)(s[i..i+data_l-1]); +     else -  r[sprintf("unknown_%07b",h)] = s[i..i+data_l-1]; -  i += data_l; +  r[id] = val;    }    return r;   }      string encode(int type, string data) {    type <<= 2;    if(sizeof(data)>65535)    return sprintf("%c%4H", type+2, data);    if(sizeof(data)>255)    return sprintf("%c%2H", type+1, data);
pike.git/lib/modules/Crypto.pmod/PGP.pmod:355: Inside #if constant(Crypto.HashState)
   ret->hash = ret->hash/",";       if( m->trailer )    ret->checksum = (int)Gmp.mpz(m->trailer,256);       ret->armor_header = m->pre;    ret->data = m->body;    ret->actual_checksum = crc24(ret->data);    return ret;   } -  - #else - constant this_program_does_not_exist=1; - #endif +