diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index aadb5889066d705c85b6a259aa46f957c2dfb0ca..6a0f174afa7e0b206549bc784c26f943179a7fcb 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -1390,6 +1390,157 @@ class SimpleSAML_Utilities {
 		return $error['message'];
 	}
 
+
+	/**
+	 * Get public key or certificate from metadata.
+	 *
+	 * This function implements a function to retrieve the public key or certificate from
+	 * a metadata array.
+	 *
+	 * It will search for the following elements in the metadata:
+	 * 'certData'  The certificate as a base64-encoded string.
+	 * 'certificate'  A file with a certificate or public key in PEM-format.
+	 * 'certFingerprint'  The fingerprint of the certificate. Can be a single fingerprint,
+	 *                    or an array of multiple valid fingerprints.
+	 *
+	 * This function will return an array with these elements:
+	 * 'PEM'  The public key/certificate in PEM-encoding.
+	 * 'certData'  The certificate data, base64 encoded, on a single line. (Only
+	 *             present if this is a certificate.)
+	 * 'certFingerprint'  Array of valid certificate fingerprints. (Only present
+	 *                    if this is a certificate.)
+	 *
+	 * @param array $metadata  The metadata array.
+	 * @param bool $required  Whether the private key is required. If this is TRUE, a
+	 *                        missing key will cause an exception. Default is FALSE.
+	 * @param string $prefix  The prefix which should be used when reading from the metadata
+	 *                        array. Defaults to ''.
+	 * @return array|NULL  Public key or certificate data, or NULL if no public key or
+	 *                     certificate was found.
+	 */
+	public static function loadPublicKey($metadata, $required = FALSE, $prefix = '') {
+		assert('is_array($metadata)');
+		assert('is_bool($required)');
+		assert('is_string($prefix)');
+
+		$ret = array();
+
+		if (array_key_exists($prefix . 'certData', $metadata)) {
+			/* Full certificate data available from metadata. */
+			$ret['certData'] = $metadata[$prefix . 'certData'];
+
+			/* Recreate PEM-encoded certificate. */
+			$ret['PEM'] = "-----BEGIN CERTIFICATE-----\n" .
+				chunk_split($ret['certData'], 64) .
+				"-----END CERTIFICATE-----\n";
+
+		} elseif (array_key_exists($prefix . 'certificate', $metadata)) {
+			/* Reference to certificate file. */
+			$config = SimpleSAML_Configuration::getInstance();
+			$file = $config->getPathValue('certdir') . $metadata[$prefix . 'certificate'];
+			$data = @file_get_contents($file);
+			if ($data === FALSE) {
+				throw new Exception('Unable to load certificate/public key from file "' . $file . '"');
+			}
+			$ret['PEM'] = $data;
+
+			/* Extract certificate data (if this is a certificate). */
+			$pattern = '/^-----BEGIN CERTIFICATE-----$([^-]*)^-----END CERTIFICATE-----$/m';
+			if (preg_match($pattern, $data, $matches)) {
+				/* We have a certificate. */
+				$ret['certData'] = str_replace(array("\r", "\n"), '', $matches[1]);
+			}
+
+		} elseif (array_key_exists($prefix . 'certFingerprint', $metadata)) {
+			/* We only have a fingerprint available. */
+			$fps = $metadata[$prefix . 'certFingerprint'];
+
+			if (!is_array($fps)) {
+				$fps = array($fps);
+			}
+
+			/* Normalize fingerprint(s) - lowercase and no colons. */
+			foreach($fps as &$fp) {
+				assert('is_string($fp)');
+				$fp = strtolower(str_replace(':', '', $fp));
+			}
+
+			/* We can't build a full certificate from a fingerprint, and may as well
+			 * return an array with only the fingerprint(s) immediately.
+			 */
+			return array('certFingerprint' => $fp);
+
+		} else {
+			/* No public key/certificate available. */
+			if ($required) {
+				throw new Exception('No public key / certificate found in metadata.');
+			} else {
+				return NULL;
+			}
+		}
+
+		if (array_key_exists('certData', $ret)) {
+			/* This is a certificate - calculate the fingerprint. */
+			$ret['certFingerprint'] = array(
+				strtolower(sha1(base64_decode($ret['certData'])))
+			);
+		}
+
+		return $ret;
+	}
+
+
+	/**
+	 * Load private key from metadata.
+	 *
+	 * This function loads a private key from a metadata array. It searches for the
+	 * following elements:
+	 * 'privatekey'  Name of a private key file in the cert-directory.
+	 * 'privatekey_pass'  Password for the private key.
+	 *
+	 * It returns and array with the following elements:
+	 * 'PEM'  Data for the private key, in PEM-format
+	 * 'password'  Password for the private key.
+	 *
+	 * @param array $metadata  The metadata array the private key should be loaded from.
+	 * @param bool $required  Whether the private key is required. If this is TRUE, a
+	 *                        missing key will cause an exception. Default is FALSE.
+	 * @param string $prefix  The prefix which should be used when reading from the metadata
+	 *                        array. Defaults to ''.
+	 * @return array|NULL  Extracted private key, or NULL if no private key is present.
+	 */
+	public static function loadPrivateKey($metadata, $required = FALSE, $prefix = '') {
+		assert('is_array($metadata)');
+		assert('is_bool($required)');
+		assert('is_string($prefix)');
+
+		if (!array_key_exists($prefix . 'privatekey', $metadata)) {
+			/* No private key found. */
+			if ($required) {
+				throw new Exception('No private key found in metadata.');
+			} else {
+				return NULL;
+			}
+		}
+
+		$config = SimpleSAML_Configuration::getInstance();
+		$file = $config->getPathValue('certdir') . $metadata[$prefix . 'privatekey'];
+		$data = @file_get_contents($file);
+		if ($data === FALSE) {
+			throw new Exception('Unable to load private key from file "' . $file . '"');
+		}
+
+		$ret = array(
+			'PEM' => $data,
+		);
+
+		if (array_key_exists($prefix . 'privatekey_pass', $metadata)) {
+			$ret['password'] = $metadata[$prefix . 'privatekey_pass'];
+		}
+
+		return $ret;
+	}
+
 }
 
 ?>
\ No newline at end of file