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 Tag implementation. 26 * 27 * @throws GTException 28 * @package asn1 29 */ 30class ASN1Tag extends ASN1Object { 31 32 private $bytes; 33 private $object; 34 35 private $explicit = true; 36 37 /** 38 * Decodes an ASN1Tag from the given byte stream. 39 * 40 * @param $bytes V bytes from the encoding of an ASN1Tag TLV 41 * @return void 42 */ 43 public function decodeDER($bytes) { 44 $this->bytes = $bytes; 45 } 46 47 /** 48 * Encodes the contents of this ASN1Tag. 49 * 50 * @throws GTException 51 * @return array array of bytes containing the encoding of this ASN1Tag 52 * @see setExplicit 53 * @see setObject 54 */ 55 public function encodeDER() { 56 57 $bytes = array(); 58 59 if ($this->object != null) { 60 61 // this is for objects we have actually decoded 62 $this->append($bytes, $this->object->encodeDER()); 63 64 } else if ($this->bytes != null) { 65 66 // for passthrough objects that we don't decode (like x509 certs) 67 $this->append($bytes, $this->bytes); 68 69 } else { 70 71 throw new GTException("Nothing to encode inside ASN1Tag"); 72 73 } 74 75 if ($this->explicit) { 76 77 $this->prepend($bytes, ASN1DER::encodeLength(count($bytes))); 78 $this->prepend($bytes, array(0)); // placeholder 79 80 } 81 82 $tag = $this->tagValue; 83 84 if ($this->tagType == ASN1_TAG_CONSTRUCTED) { 85 $tag = $tag | 0x20; 86 } 87 88 switch ($this->tagClass) { 89 90 case ASN1_TAG_APPLICATION: 91 $tag = $tag | 0x40; 92 break; 93 94 case ASN1_TAG_PRIVATE: 95 $tag = $tag | 0xC0; 96 break; 97 98 case ASN1_TAG_CONTEXT: 99 $tag = $tag | 0x80; 100 break; 101 102 } 103 104 $bytes[0] = $tag; 105 106 return $bytes; 107 108 } 109 110 /** 111 * Return the object embedded inside this ASN.1 Tag. 112 * 113 * This method is for explicit tags only. 114 * 115 * @throws GTException 116 * @return ASN1Object object embedded inside this tag 117 */ 118 public function getObject() { 119 $object = ASN1DER::decodeType($this->bytes); 120 $length = ASN1DER::decodeLength($this->bytes); 121 122 $object->decodeDER($this->readBytes($this->bytes, $length)); 123 124 if (count($this->bytes) > 0) { 125 throw new GTException("Invalid explicit tag encoding with trailing bytes"); 126 } 127 128 return $object; 129 } 130 131 /** 132 * Returns the object embedded inside this ASN.1 Tag. 133 * 134 * This method is for implicit tags only. 135 * 136 * @param $tag the type of asn1 object to decode this tag as 137 * @return ASN1Object object embedded inside this tag 138 */ 139 public function getObjectAs($tag) { 140 141 $tag = array($tag); 142 143 $object = ASN1DER::decodeType($tag); 144 $object->decodeDER($this->bytes); 145 146 return $object; 147 } 148 149 /** 150 * Sets the object embedded inside this ASN.1 Tag. 151 * 152 * @param ASN1Object $object ASN1Object to embed inside this tag 153 * @return void 154 */ 155 public function setObject($object) { 156 $this->object = $object; 157 } 158 159 160 /** 161 * Marks this tag as explicit. 162 * 163 * @param $explicit boolean indicating if this tag is explicit 164 * @return void 165 */ 166 public function setExplicit($explicit) { 167 $this->explicit = $explicit; 168 } 169 170 /** 171 * Checks if this tag is marked as explicit. 172 * 173 * @return bool true when this tag is explicit 174 */ 175 public function isExplicit() { 176 return $this->explicit; 177 } 178 179} 180 181?> 182