1<?php 2/* 3 * Copyright 2008-2010 GuardTime AS 4 * 5 * This file is part of the GuardTime PHP SDK. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20/** 21 * @package asn1 22 */ 23 24/** 25 * ASN.1 Object Id implementation. 26 * 27 * @package asn1 28 */ 29class ASN1ObjectId extends ASN1Object { 30 31 protected static $ALLOWED_CHARACTERS = array( 32 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.' 33 ); 34 35 protected $value; 36 37 /** 38 * Constructs a new ASN.1 Object Id. 39 * 40 * @param string $value value as string 41 * @return void 42 */ 43 public function __construct($value = null) { 44 45 if (!is_null($value)) { 46 47 if (strlen($value) == 0) { 48 throw new GTException("Invalid OID: 0 length"); 49 } 50 51 foreach (GTUtil::toArray($value) as $char) { 52 53 if (!in_array($char, self::$ALLOWED_CHARACTERS, true)) { 54 throw new GTException("Invalid OID: character {$char} not allowed"); 55 } 56 57 } 58 59 $tokens = explode('.', $value); 60 61 if (count($tokens) < 2) { 62 throw new GTException("Invaid OID: must contain at least 2 '.' separated tokens"); 63 } 64 65 $this->value = $value; 66 } 67 68 } 69 70 /** 71 * Gets the value of this object id. 72 * 73 * @return string value 74 */ 75 public function getValue() { 76 return $this->value; 77 } 78 79 /** 80 * Encodes the contents of this ASN1 Object Id as DER. 81 * 82 * @return array DER encoding of this object Id 83 */ 84 public function encodeDER() { 85 86 $bytes = array(); 87 88 $tokens = explode('.', $this->value); 89 90 $b1 = (int) array_shift($tokens); 91 $b2 = (int) array_shift($tokens); 92 93 $this->append($bytes, ($b1 * 40 + $b2)); 94 95 $zero = new GTBigInteger(0); 96 97 $mask1 = new GTBigInteger(0x80); 98 $mask2 = new GTBigInteger(0x7F); 99 100 foreach ($tokens as $token) { 101 102 $integer = new GTBigInteger($token); 103 104 $size = 1; 105 $buff = $integer; 106 107 while (true) { 108 109 $buff = $buff->shiftRight(7); 110 111 if ($buff->comp($zero) == 0) { 112 break; 113 } 114 115 $size++; 116 } 117 118 for ($i = ($size - 1) * 7; $i >= 0; $i -= 7) { 119 120 if ($i == 0) { 121 $this->append($bytes, (int) $integer->bitAnd($mask2)->getValue()); 122 123 } else { 124 $this->append($bytes, (int) $integer->shiftRight($i)->bitAnd($mask2)->bitOr($mask1)->getValue()); 125 } 126 127 } 128 } 129 130 $this->prepend($bytes, ASN1DER::encodeLength(count($bytes))); 131 $this->prepend($bytes, ASN1DER::encodeType(ASN1_TAG_OBJECT_ID)); 132 133 return $bytes; 134 135 } 136 137 /** 138 * Decodes an ASN1ObjectId from the given byte stream. 139 * 140 * @param $bytes V bytes from the encoding of ASN1ObjectId TLV. 141 * @return void 142 */ 143 public function decodeDER($bytes) { 144 145 $this->value = ''; 146 147 $current = null; 148 149 for ($i = 0; $i < count($bytes); $i++) { 150 151 if ($current == null) { 152 $current = new GTBigInteger(0); 153 } 154 155 $byte = $bytes[$i]; 156 157 $current = $current->shiftLeft(7); 158 $current = $current->bitOr(new GTBigInteger($byte & 0x7F)); 159 160 if (($byte & 0x80) != 0) { 161 continue; 162 } 163 164 if ($i == 0) { 165 166 // int is always big enough to hold the first chunk 167 168 $current = (int) $current->getValue(); 169 170 if ($current < 40) { 171 $byte1 = 0; 172 173 } else if ($current < 80) { 174 $byte1 = 1; 175 176 } else { 177 $byte1 = 2; 178 } 179 180 $byte2 = $current - ($byte1 * 40); 181 182 $this->value .= $byte1; 183 $this->value .= '.'; 184 $this->value .= $byte2; 185 $this->value .= '.'; 186 187 $current = null; 188 189 } else { 190 191 $this->value .= $current->getValue(); 192 193 if ($i != count($bytes) - 1) { 194 $this->value .= '.'; 195 } 196 197 $current = null; 198 199 } 200 201 } 202 203 } 204} 205 206?> 207