[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/lcobucci/jwt/src/Signer/Ecdsa/ -> MultibyteStringConverter.php (source)

   1  <?php
   2  /*
   3   * The MIT License (MIT)
   4   *
   5   * Copyright (c) 2014-2018 Spomky-Labs
   6   *
   7   * This software may be modified and distributed under the terms
   8   * of the MIT license.  See the LICENSE file for details.
   9   *
  10   * @link https://github.com/web-token/jwt-framework/blob/v1.2/src/Component/Core/Util/ECSignature.php
  11   */
  12  namespace Lcobucci\JWT\Signer\Ecdsa;
  13  
  14  use function bin2hex;
  15  use function dechex;
  16  use function hex2bin;
  17  use function hexdec;
  18  use function mb_strlen;
  19  use function mb_substr;
  20  use function str_pad;
  21  use const STR_PAD_LEFT;
  22  
  23  /**
  24   * ECDSA signature converter using ext-mbstring
  25   *
  26   * @internal
  27   */
  28  final class MultibyteStringConverter implements SignatureConverter
  29  {
  30      const ASN1_SEQUENCE          = '30';
  31      const ASN1_INTEGER           = '02';
  32      const ASN1_MAX_SINGLE_BYTE   = 128;
  33      const ASN1_LENGTH_2BYTES     = '81';
  34      const ASN1_BIG_INTEGER_LIMIT = '7f';
  35      const ASN1_NEGATIVE_INTEGER  = '00';
  36      const BYTE_SIZE              = 2;
  37  
  38      public function toAsn1($signature, $length)
  39      {
  40          $signature = bin2hex($signature);
  41  
  42          if (self::octetLength($signature) !== $length) {
  43              throw ConversionFailed::invalidLength();
  44          }
  45  
  46          $pointR = self::preparePositiveInteger(mb_substr($signature, 0, $length, '8bit'));
  47          $pointS = self::preparePositiveInteger(mb_substr($signature, $length, null, '8bit'));
  48  
  49          $lengthR = self::octetLength($pointR);
  50          $lengthS = self::octetLength($pointS);
  51  
  52          $totalLength  = $lengthR + $lengthS + self::BYTE_SIZE + self::BYTE_SIZE;
  53          $lengthPrefix = $totalLength > self::ASN1_MAX_SINGLE_BYTE ? self::ASN1_LENGTH_2BYTES : '';
  54  
  55          $asn1 = hex2bin(
  56              self::ASN1_SEQUENCE
  57              . $lengthPrefix . dechex($totalLength)
  58              . self::ASN1_INTEGER . dechex($lengthR) . $pointR
  59              . self::ASN1_INTEGER . dechex($lengthS) . $pointS
  60          );
  61  
  62          return $asn1;
  63      }
  64  
  65      private static function octetLength($data)
  66      {
  67          return (int) (mb_strlen($data, '8bit') / self::BYTE_SIZE);
  68      }
  69  
  70      private static function preparePositiveInteger($data)
  71      {
  72          if (mb_substr($data, 0, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) {
  73              return self::ASN1_NEGATIVE_INTEGER . $data;
  74          }
  75  
  76          while (mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
  77              && mb_substr($data, 2, self::BYTE_SIZE, '8bit') <= self::ASN1_BIG_INTEGER_LIMIT) {
  78              $data = mb_substr($data, 2, null, '8bit');
  79          }
  80  
  81          return $data;
  82      }
  83  
  84      public function fromAsn1($signature, $length)
  85      {
  86          $message  = bin2hex($signature);
  87          $position = 0;
  88  
  89          if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_SEQUENCE) {
  90              throw ConversionFailed::incorrectStartSequence();
  91          }
  92  
  93          if (self::readAsn1Content($message, $position, self::BYTE_SIZE) === self::ASN1_LENGTH_2BYTES) {
  94              $position += self::BYTE_SIZE;
  95          }
  96  
  97          $pointR = self::retrievePositiveInteger(self::readAsn1Integer($message, $position));
  98          $pointS = self::retrievePositiveInteger(self::readAsn1Integer($message, $position));
  99  
 100          $points = hex2bin(str_pad($pointR, $length, '0', STR_PAD_LEFT) . str_pad($pointS, $length, '0', STR_PAD_LEFT));
 101  
 102          return $points;
 103      }
 104  
 105      private static function readAsn1Content($message, &$position, $length)
 106      {
 107          $content   = mb_substr($message, $position, $length, '8bit');
 108          $position += $length;
 109  
 110          return $content;
 111      }
 112  
 113      private static function readAsn1Integer($message, &$position)
 114      {
 115          if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_INTEGER) {
 116              throw ConversionFailed::integerExpected();
 117          }
 118  
 119          $length = (int) hexdec(self::readAsn1Content($message, $position, self::BYTE_SIZE));
 120  
 121          return self::readAsn1Content($message, $position, $length * self::BYTE_SIZE);
 122      }
 123  
 124      private static function retrievePositiveInteger($data)
 125      {
 126          while (mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
 127              && mb_substr($data, 2, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) {
 128              $data = mb_substr($data, 2, null, '8bit');
 129          }
 130  
 131          return $data;
 132      }
 133  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer