From 660b8895ecbe93ce158a5045b23c91e1b79229da Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 26 Jul 2013 17:04:32 -0500 Subject: [PATCH] ASN1, X509: replace user_error's with exceptions --- phpseclib/File/ASN1.php | 19 ++++--- phpseclib/File/X509.php | 107 ++++++++++++++++++++++++++-------------- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 6d89fe1..8ad2838 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -106,6 +106,16 @@ define('FILE_ASN1_TYPE_ANY', -2); /**#@-*/ +/** + * ASN1ParseException + * + * @author Jim Wigginton + * @version 0.3.5 + * @access public + * @package File_ASN1 + */ +class ASN1ParseException extends Exception {} + /** * ASN.1 Element * @@ -975,8 +985,7 @@ function _encode_der($source, $mapping, $idx = NULL) case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); if ($oid === false) { - user_error('Invalid OID'); - return false; + throw new ASN1ParseException('Invalid OID'); } $value = ''; $parts = explode('.', $oid); @@ -1028,8 +1037,7 @@ function _encode_der($source, $mapping, $idx = NULL) $filters = $filters[$part]; } if ($filters === false) { - user_error('No filters defined for ' . implode('/', $loc)); - return false; + throw new ASN1ParseException('No filters defined for ' . implode('/', $loc)); } return $this->_encode_der($source, $filters + $mapping); case FILE_ASN1_TYPE_NULL: @@ -1052,8 +1060,7 @@ function _encode_der($source, $mapping, $idx = NULL) $value = $source ? "\xFF" : "\x00"; break; default: - user_error('Mapping provides no type definition for ' . implode('/', $this->location)); - return false; + throw new ASN1ParseException('Mapping provides no type definition for ' . implode('/', $this->location)); } if (isset($idx)) { diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 837fe31..2b6baf4 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -121,6 +121,36 @@ define('FILE_X509_ATTR_APPEND', -2); // Add a value. define('FILE_X509_ATTR_REPLACE', -3); // Clear first, then add a value. +/** + * MalformedX509Exception + * + * @author Jim Wigginton + * @version 0.3.5 + * @access public + * @package File_X509 + */ +class MalformedX509Exception extends Exception {} + +/** + * CertNotLoadedException + * + * @author Jim Wigginton + * @version 0.3.5 + * @access public + * @package File_X509 + */ +class CertNotLoadedException extends Exception {} + +/** + * UnsupportedAlgorithmException + * + * @author Jim Wigginton + * @version 0.3.5 + * @access public + * @package File_X509 + */ +class UnsupportedAlgorithmException extends Exception {} + /** * Pure-PHP X.509 Parser * @@ -1422,7 +1452,7 @@ function loadX509($cert) unset($this->currentKeyIdentifier); $this->dn = $cert['tbsCertificate']['subject']; if (!isset($this->dn)) { - return false; + throw new MalformedX509Exception('No distinguished name found in X.509 array'); } $this->currentCert = $cert; @@ -1440,7 +1470,7 @@ function loadX509($cert) if ($cert === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode ASN.1'); } $asn1->loadOIDs($this->oids); @@ -1451,7 +1481,7 @@ function loadX509($cert) } if (!isset($x509) || $x509 === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to map BER-decoded data to X.509 format'); } $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); @@ -1636,7 +1666,7 @@ function _mapOutExtensions(&$root, $path, $asn1) $map = $this->_getMapping($id); if (is_bool($map)) { if (!$map) { - user_error($id . ' is not a currently supported extension'); + //user_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { @@ -1709,7 +1739,7 @@ function _mapOutAttributes(&$root, $path, $asn1) $id = $attributes[$i]['type']; $map = $this->_getMapping($id); if ($map === false) { - user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); unset($attributes[$i]); } elseif (is_array($attributes[$i]['value'])) { @@ -1849,7 +1879,7 @@ function loadCA($cert) $this->signatureSubject = $oldsigsubj; $this->currentKeyIdentifier = $oldkeyid; - return false; + throw new MalformedX509Exception('Unable to load X.509 CA'); } /* From RFC5280 "PKIX Certificate and CRL Profile": @@ -1905,7 +1935,7 @@ function loadCA($cert) function validateURL($url) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { - return false; + throw new CertNotLoadedException(); } $components = parse_url($url); @@ -1962,7 +1992,7 @@ function validateURL($url) function validateDate($date = NULL) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { - return false; + throw new CertNotLoadedException(); } if (!isset($date)) { @@ -2002,7 +2032,7 @@ function validateDate($date = NULL) function validateSignature($caonly = true) { if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { - return 0; + throw new CertNotLoadedException(); } /* TODO: @@ -2138,11 +2168,11 @@ function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm } break; default: - return NULL; + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; default: - return NULL; + throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); } return true; @@ -2740,14 +2770,17 @@ function getPublicKey() return $this->publicKey; } - if (isset($this->currentCert) && is_array($this->currentCert)) { - foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) { - $keyinfo = $this->_subArray($this->currentCert, $path); - if (!empty($keyinfo)) { - break; - } + if (!isset($this->currentCert) || !is_array($this->currentCert)) { + throw new CertNotLoadedException(); + } + + foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) { + $keyinfo = $this->_subArray($this->currentCert, $path); + if (!empty($keyinfo)) { + break; } } + if (empty($keyinfo)) { return false; } @@ -2801,7 +2834,7 @@ function loadCSR($csr) if ($csr === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode ASN.1'); } $asn1->loadOIDs($this->oids); @@ -2815,7 +2848,7 @@ function loadCSR($csr) $csr = $asn1->asn1map($decoded[0], $this->CertificationRequest); if (!isset($csr) || $csr === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to map BER-decoded data to CSR format'); } $this->dn = $csr['certificationRequestInfo']['subject']; @@ -2928,7 +2961,7 @@ function loadSPKAC($csr) if ($csr === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode base64'); } $asn1->loadOIDs($this->oids); @@ -2936,14 +2969,14 @@ function loadSPKAC($csr) if (empty($decoded)) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode ASN.1'); } $csr = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge); if (!isset($csr) || $csr === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to map BER-decoded data to SPKAC format'); } $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); @@ -2993,7 +3026,7 @@ function loadCRL($crl) if ($crl === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode base64'); } $asn1->loadOIDs($this->oids); @@ -3001,13 +3034,13 @@ function loadCRL($crl) if (empty($decoded)) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to decode ASN.1'); } $crl = $asn1->asn1map($decoded[0], $this->CertificateList); if (!isset($crl) || $crl === false) { $this->currentCert = false; - return false; + throw new MalformedX509Exception('Unable to map BER-decoded data to X.509 format'); } $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); @@ -3037,7 +3070,7 @@ function loadCRL($crl) function saveCRL($crl, $format = FILE_X509_FORMAT_PEM) { if (!is_array($crl) || !isset($crl['tbsCertList'])) { - return false; + throw new CertNotLoadedException(); } $asn1 = new File_ASN1(); @@ -3097,11 +3130,11 @@ function saveCRL($crl, $format = FILE_X509_FORMAT_PEM) function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { - return false; + throw new CertNotLoadedException('Invalid issuer data'); } if (isset($subject->publicKey) && !($subjectPublicKey = $subject->_formatSubjectPublicKey())) { - return false; + throw new CertNotLoadedException('Invalid subject data'); } $currentCert = isset($this->currentCert) ? $this->currentCert : NULL; @@ -3134,10 +3167,10 @@ function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption') $this->removeExtension('id-ce-subjectAltName'); } } else if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) { - return false; + throw new CertNotLoadedException('To sign a CRL use signCRL'); } else { if (!isset($subject->publicKey)) { - return false; + throw new CertNotLoadedException('Subject public key not loaded'); } $startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M y H:i:s O'); @@ -3244,7 +3277,7 @@ function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption') function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($this->privateKey) || empty($this->dn)) { - return false; + throw new CertNotLoadedException(); } $origPublicKey = $this->publicKey; @@ -3308,7 +3341,7 @@ function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption') function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { - return false; + throw new CertNotLoadedException(); } $currentCert = isset($this->currentCert) ? $this->currentCert : NULL; @@ -3451,7 +3484,7 @@ function _sign($key, $signatureAlgorithm) return $this->currentCert; } default: - return false; + throw new UnsupportedAlgorithmException('Unsupported public key algorithm'); } } @@ -3785,7 +3818,7 @@ function removeAttribute($id, $disposition = FILE_X509_ATTR_ALL) $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { - return false; + throw new CertNotLoadedException(); } $result = false; @@ -3840,7 +3873,7 @@ function getAttribute($id, $disposition = FILE_X509_ATTR_ALL, $csr = NULL) $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { - return false; + throw new CertNotLoadedException(); } foreach ($attributes as $key => $attribute) { @@ -3903,7 +3936,7 @@ function setAttribute($id, $value, $disposition = FILE_X509_ATTR_ALL) $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes', true); if (!is_array($attributes)) { - return false; + throw new CertNotLoadedException(); } switch ($disposition) { @@ -4078,7 +4111,7 @@ function _formatSubjectPublicKey() 'subjectPublicKey' => $this->publicKey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) ); default: - return false; + throw new UnsupportedAlgorithmException('Unsupported public key algorithm'); } }