Up to signing xml
This commit is contained in:
parent
1f4fae314c
commit
dd60eb3b58
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
namespace App\Services\EDocument\Standards\Verifactu\Models;
|
||||
|
||||
use RobRichards\XMLSecLibs\XMLSecurityDSig;
|
||||
use RobRichards\XMLSecLibs\XMLSecurityKey;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Invoice extends BaseXmlModel
|
||||
{
|
||||
protected string $idVersion;
|
||||
|
|
@ -36,6 +40,9 @@ class Invoice extends BaseXmlModel
|
|||
protected string $huella;
|
||||
protected ?string $signature = null;
|
||||
protected ?FacturaRectificativa $facturaRectificativa = null;
|
||||
protected ?string $privateKeyPath = null;
|
||||
protected ?string $publicKeyPath = null;
|
||||
protected ?string $certificatePath = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -411,6 +418,117 @@ class Invoice extends BaseXmlModel
|
|||
$this->facturaRectificativa = $facturaRectificativa;
|
||||
}
|
||||
|
||||
public function setPrivateKeyPath(string $path): self
|
||||
{
|
||||
$this->privateKeyPath = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPublicKeyPath(string $path): self
|
||||
{
|
||||
$this->publicKeyPath = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCertificatePath(string $path): self
|
||||
{
|
||||
$this->certificatePath = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function signXml(\DOMDocument $doc): void
|
||||
{
|
||||
if (!$this->privateKeyPath || !file_exists($this->privateKeyPath)) {
|
||||
throw new \RuntimeException('Private key not found or not set');
|
||||
}
|
||||
|
||||
if (!$this->certificatePath || !file_exists($this->certificatePath)) {
|
||||
throw new \RuntimeException('Certificate not found or not set');
|
||||
}
|
||||
|
||||
Log::info('Starting XML signing process');
|
||||
Log::debug('XML before signing: ' . $doc->saveXML());
|
||||
|
||||
try {
|
||||
// Create a new Security object
|
||||
Log::debug('Creating XMLSecurityDSig object');
|
||||
$objDSig = new XMLSecurityDSig();
|
||||
|
||||
// Set canonicalization method
|
||||
Log::debug('Setting canonicalization method');
|
||||
$objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
|
||||
|
||||
// Create a new Security key
|
||||
Log::debug('Creating XMLSecurityKey object');
|
||||
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'private']);
|
||||
|
||||
// Load the private key
|
||||
Log::debug('Loading private key from: ' . $this->privateKeyPath);
|
||||
$objKey->loadKey($this->privateKeyPath, true);
|
||||
|
||||
// Add reference
|
||||
Log::debug('Adding reference to document');
|
||||
$objDSig->addReference(
|
||||
$doc,
|
||||
XMLSecurityDSig::SHA256,
|
||||
['http://www.w3.org/2000/09/xmldsig#enveloped-signature']
|
||||
);
|
||||
Log::debug('Added reference to document');
|
||||
|
||||
// Add the certificate
|
||||
Log::debug('Adding certificate');
|
||||
$objDSig->add509Cert(file_get_contents($this->certificatePath));
|
||||
|
||||
// Sign the XML document
|
||||
Log::debug('Signing document');
|
||||
$objDSig->sign($objKey);
|
||||
|
||||
// Append the signature to the XML
|
||||
Log::debug('Appending signature');
|
||||
$objDSig->appendSignature($doc->documentElement);
|
||||
|
||||
Log::debug('XML after signing: ' . $doc->saveXML());
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error during XML signing: ' . $e->getMessage());
|
||||
Log::error('Stack trace: ' . $e->getTraceAsString());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function verifySignature(\DOMDocument $doc): bool
|
||||
{
|
||||
if (!$this->publicKeyPath || !file_exists($this->publicKeyPath)) {
|
||||
throw new \RuntimeException('Public key not found or not set');
|
||||
}
|
||||
|
||||
// Get the signature node
|
||||
$objXMLSecDSig = new XMLSecurityDSig();
|
||||
|
||||
// Locate the signature
|
||||
$objDSig = $objXMLSecDSig->locateSignature($doc);
|
||||
if (!$objDSig) {
|
||||
throw new \RuntimeException('Signature not found in document');
|
||||
}
|
||||
|
||||
// Canonicalize the signed info
|
||||
$objXMLSecDSig->canonicalizeSignedInfo();
|
||||
|
||||
// Validate references
|
||||
$objXMLSecDSig->validateReference();
|
||||
|
||||
// Get the key from the certificate
|
||||
$objKey = $objXMLSecDSig->locateKey();
|
||||
if (!$objKey) {
|
||||
throw new \RuntimeException('Key not found in signature');
|
||||
}
|
||||
|
||||
// Load the public key
|
||||
$objKey->loadKey($this->publicKeyPath, false, true);
|
||||
|
||||
// Verify the signature
|
||||
return $objXMLSecDSig->verify($objKey) === 1;
|
||||
}
|
||||
|
||||
public function toXml(): string
|
||||
{
|
||||
// Validate required fields first, outside of try-catch
|
||||
|
|
@ -439,8 +557,8 @@ class Invoice extends BaseXmlModel
|
|||
$doc->formatOutput = true;
|
||||
|
||||
// Create root element with proper namespaces
|
||||
$root = $doc->createElementNS(self::XML_NAMESPACE, self::XML_NAMESPACE_PREFIX . ':RegistroAlta');
|
||||
$root->setAttribute('xmlns:ds', self::XML_DS_NAMESPACE);
|
||||
$root = $doc->createElementNS(parent::XML_NAMESPACE, parent::XML_NAMESPACE_PREFIX . ':RegistroAlta');
|
||||
$root->setAttribute('xmlns:ds', parent::XML_DS_NAMESPACE);
|
||||
$doc->appendChild($root);
|
||||
|
||||
// Add required elements in exact order according to schema
|
||||
|
|
@ -617,12 +735,19 @@ class Invoice extends BaseXmlModel
|
|||
$root->appendChild($signatureElement);
|
||||
}
|
||||
|
||||
$xml = $doc->saveXML($root);
|
||||
// error_log("Generated XML: " . $xml);
|
||||
return $xml;
|
||||
// Sign the document if private key is set
|
||||
if ($this->privateKeyPath !== null) {
|
||||
try {
|
||||
$this->signXml($doc);
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException('Failed to sign XML: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $doc->saveXML();
|
||||
} catch (\Exception $e) {
|
||||
error_log("Error in toXml: " . $e->getMessage());
|
||||
throw $e;
|
||||
throw new \RuntimeException("Error in toXml: " . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@
|
|||
"pusher/pusher-php-server": "^7.2",
|
||||
"quickbooks/v3-php-sdk": "^6.2",
|
||||
"razorpay/razorpay": "2.*",
|
||||
"robrichards/xmlseclibs": "^3.1",
|
||||
"sentry/sentry-laravel": "^4",
|
||||
"setasign/fpdf": "^1.8",
|
||||
"setasign/fpdi": "^2.3",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3469affb27a6e61c80c53267c6ca2889",
|
||||
"content-hash": "df5805c56ea07b9fe22be83885c67387",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adrienrn/php-mimetyper",
|
||||
|
|
@ -5169,16 +5169,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v11.44.2",
|
||||
"version": "v11.44.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "f85216c82cbd38b66d67ebd20ea762cb3751a4b4"
|
||||
"reference": "819555ccc7e88ea92945ea785ef9f0fa9b6d4931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/f85216c82cbd38b66d67ebd20ea762cb3751a4b4",
|
||||
"reference": "f85216c82cbd38b66d67ebd20ea762cb3751a4b4",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/819555ccc7e88ea92945ea785ef9f0fa9b6d4931",
|
||||
"reference": "819555ccc7e88ea92945ea785ef9f0fa9b6d4931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5380,7 +5380,7 @@
|
|||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2025-03-12T14:34:30+00:00"
|
||||
"time": "2025-04-24T13:59:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/octane",
|
||||
|
|
@ -11027,6 +11027,48 @@
|
|||
},
|
||||
"time": "2025-01-21T10:13:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robrichards/xmlseclibs.git",
|
||||
"reference": "2bdfd742624d739dfadbd415f00181b4a77aaf07"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/2bdfd742624d739dfadbd415f00181b4a77aaf07",
|
||||
"reference": "2bdfd742624d739dfadbd415f00181b4a77aaf07",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"php": ">= 5.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RobRichards\\XMLSecLibs\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "A PHP library for XML Security",
|
||||
"homepage": "https://github.com/robrichards/xmlseclibs",
|
||||
"keywords": [
|
||||
"security",
|
||||
"signature",
|
||||
"xml",
|
||||
"xmldsig"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robrichards/xmlseclibs/issues",
|
||||
"source": "https://github.com/robrichards/xmlseclibs/tree/3.1.3"
|
||||
},
|
||||
"time": "2024-11-20T21:13:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v8.8.0",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Tests\Feature\EInvoice\Verifactu\Models;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Tests\TestCase;
|
||||
use App\Services\EDocument\Standards\Verifactu\Models\BaseXmlModel;
|
||||
|
||||
abstract class BaseModelTest extends TestCase
|
||||
|
|
|
|||
|
|
@ -789,10 +789,9 @@ class InvoiceTest extends BaseModelTest
|
|||
->setImporteTotal(100.00)
|
||||
->setFechaHoraHusoGenRegistro('2023-01-01T12:00:00')
|
||||
->setTipoHuella('01')
|
||||
->setHuella('abc123...')
|
||||
->setSignature('MOCK_SIGNATURE_VALUE');
|
||||
->setHuella('abc123...');
|
||||
|
||||
// Add sistema informatico
|
||||
// Add sistema informatico with all required fields
|
||||
$sistema = new SistemaInformatico();
|
||||
$sistema
|
||||
->setNombreRazon('Sistema de Facturación')
|
||||
|
|
@ -800,15 +799,74 @@ class InvoiceTest extends BaseModelTest
|
|||
->setNombreSistemaInformatico('SistemaFacturacion')
|
||||
->setIdSistemaInformatico('01')
|
||||
->setVersion('1.0')
|
||||
->setNumeroInstalacion('INST-001');
|
||||
->setNumeroInstalacion('INST-001')
|
||||
->setTipoUsoPosibleSoloVerifactu('S')
|
||||
->setTipoUsoPosibleMultiOT('S')
|
||||
->setIndicadorMultiplesOT('S');
|
||||
$invoice->setSistemaInformatico($sistema);
|
||||
|
||||
$xml = $invoice->toXml();
|
||||
$this->assertValidatesAgainstXsd($xml, $this->getTestXsdPath());
|
||||
// Add desglose with proper structure
|
||||
$desglose = new Desglose();
|
||||
$desglose->setDesgloseIVA([
|
||||
'Impuesto' => '01',
|
||||
'ClaveRegimen' => '02',
|
||||
'CalificacionOperacion' => 'S2',
|
||||
'BaseImponible' => 100.00,
|
||||
'TipoImpositivo' => 21,
|
||||
'Cuota' => 21.00
|
||||
]);
|
||||
$invoice->setDesglose($desglose);
|
||||
|
||||
// Test deserialization
|
||||
$deserialized = Invoice::fromXml($xml);
|
||||
$this->assertEquals('MOCK_SIGNATURE_VALUE', $deserialized->getSignature());
|
||||
// Add encadenamiento (required)
|
||||
$encadenamiento = new Encadenamiento();
|
||||
$encadenamiento->setPrimerRegistro('S');
|
||||
$invoice->setEncadenamiento($encadenamiento);
|
||||
|
||||
// Set up paths for certificates
|
||||
$certsPath = dirname(__DIR__) . '/certs/';
|
||||
$privateKeyPath = $certsPath . 'private.pem';
|
||||
$publicKeyPath = $certsPath . 'public.pem';
|
||||
$certificatePath = $certsPath . 'certificate.pem';
|
||||
|
||||
// Check if certificate files exist and are readable
|
||||
foreach (['private.pem', 'public.pem', 'certificate.pem'] as $file) {
|
||||
$path = $certsPath . $file;
|
||||
echo "\n$file: ";
|
||||
if (!file_exists($path)) {
|
||||
echo "MISSING";
|
||||
throw new \RuntimeException("Certificate file $file does not exist at $path");
|
||||
}
|
||||
if (!is_readable($path)) {
|
||||
echo "NOT READABLE";
|
||||
throw new \RuntimeException("Certificate file $file is not readable at $path");
|
||||
}
|
||||
echo "OK (size: " . filesize($path) . " bytes)";
|
||||
}
|
||||
|
||||
// Set the keys
|
||||
$invoice->setPrivateKeyPath($privateKeyPath)
|
||||
->setPublicKeyPath($publicKeyPath)
|
||||
->setCertificatePath($certificatePath);
|
||||
|
||||
// Generate signed XML
|
||||
$xml = $invoice->toXml();
|
||||
|
||||
// Debug output
|
||||
echo "\nGenerated XML with signature:\n";
|
||||
echo $xml;
|
||||
echo "\n\n";
|
||||
|
||||
// Load the XML into a DOMDocument for verification
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($xml);
|
||||
|
||||
// Verify the signature
|
||||
$this->assertTrue($invoice->verifySignature($doc));
|
||||
|
||||
// Skip schema validation for signed XML since the signature schema is not part of the core invoice schema
|
||||
// Instead, validate the XML before signing
|
||||
$unsignedXml = $invoice->toXml(false);
|
||||
$this->assertValidatesAgainstXsd($unsignedXml, $this->getTestXsdPath());
|
||||
}
|
||||
|
||||
public function testCreateAndSerializeInvoiceWithAgreementData(): void
|
||||
|
|
@ -1140,4 +1198,78 @@ class InvoiceTest extends BaseModelTest
|
|||
throw new \DOMException('XML does not validate against schema');
|
||||
}
|
||||
}
|
||||
|
||||
public function testSignatureGeneration(): void
|
||||
{
|
||||
$invoice = new Invoice();
|
||||
$invoice->setIdVersion('1.0')
|
||||
->setIdFactura('TEST123')
|
||||
->setNombreRazonEmisor('Test Company')
|
||||
->setTipoFactura('F1')
|
||||
->setDescripcionOperacion('Test Operation')
|
||||
->setCuotaTotal(100.00)
|
||||
->setImporteTotal(121.00)
|
||||
->setFechaHoraHusoGenRegistro(date('Y-m-d\TH:i:s'))
|
||||
->setTipoHuella('SHA-256')
|
||||
->setHuella(hash('sha256', 'test'));
|
||||
|
||||
// Set up the desglose
|
||||
$desglose = new Desglose();
|
||||
$desglose->setDesgloseIVA([
|
||||
'Impuesto' => 'IVA',
|
||||
'ClaveRegimen' => '01',
|
||||
'BaseImponible' => 100.00,
|
||||
'TipoImpositivo' => 21.00,
|
||||
'Cuota' => 21.00
|
||||
]);
|
||||
$invoice->setDesglose($desglose);
|
||||
|
||||
// Set up encadenamiento
|
||||
$encadenamiento = new Encadenamiento();
|
||||
$encadenamiento->setPrimerRegistro('1');
|
||||
$invoice->setEncadenamiento($encadenamiento);
|
||||
|
||||
// Set up sistema informatico
|
||||
$sistemaInformatico = new SistemaInformatico();
|
||||
$sistemaInformatico->setNombreRazon('Test System')
|
||||
->setNif('12345678Z')
|
||||
->setNombreSistemaInformatico('Test Software')
|
||||
->setIdSistemaInformatico('TEST001')
|
||||
->setVersion('1.0')
|
||||
->setNumeroInstalacion('001')
|
||||
->setTipoUsoPosibleSoloVerifactu('S')
|
||||
->setTipoUsoPosibleMultiOT('S')
|
||||
->setIndicadorMultiplesOT('S');
|
||||
$invoice->setSistemaInformatico($sistemaInformatico);
|
||||
|
||||
// Set up signature keys
|
||||
$privateKeyPath = dirname(__DIR__) . '/certs/private.pem';
|
||||
$publicKeyPath = dirname(__DIR__) . '/certs/public.pem';
|
||||
$certificatePath = dirname(__DIR__) . '/certs/certificate.pem';
|
||||
|
||||
// Set the keys
|
||||
$invoice->setPrivateKeyPath($privateKeyPath)
|
||||
->setPublicKeyPath($publicKeyPath)
|
||||
->setCertificatePath($certificatePath);
|
||||
|
||||
// Generate signed XML
|
||||
$xml = $invoice->toXml();
|
||||
|
||||
// Debug output
|
||||
echo "\nGenerated XML with signature:\n";
|
||||
echo $xml;
|
||||
echo "\n\n";
|
||||
|
||||
// Load the XML into a DOMDocument for verification
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($xml);
|
||||
|
||||
// Verify the signature
|
||||
$this->assertTrue($invoice->verifySignature($doc));
|
||||
|
||||
// Validate against schema
|
||||
$this->assertValidatesAgainstXsd($xml, $this->getTestXsdPath());
|
||||
|
||||
// Clean up test keys
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEITCCAwmgAwIBAgIULRklu/Ae+uWUdejwvfO7wKhs0lIwDQYJKoZIhvcNAQEL
|
||||
BQAwgZ8xCzAJBgNVBAYTAkVTMQ8wDQYDVQQIDAZNYWRyaWQxDzANBgNVBAcMBk1h
|
||||
ZHJpZDEaMBgGA1UECgwRVGVzdCBPcmdhbml6YXRpb24xFjAUBgNVBAsMDUlUIERl
|
||||
cGFydG1lbnQxGTAXBgNVBAMMEHRlc3QuZXhhbXBsZS5jb20xHzAdBgkqhkiG9w0B
|
||||
CQEWEHRlc3RAZXhhbXBsZS5jb20wHhcNMjUwNDI1MDQxMzA2WhcNMjYwNDI1MDQx
|
||||
MzA2WjCBnzELMAkGA1UEBhMCRVMxDzANBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwG
|
||||
TWFkcmlkMRowGAYDVQQKDBFUZXN0IE9yZ2FuaXphdGlvbjEWMBQGA1UECwwNSVQg
|
||||
RGVwYXJ0bWVudDEZMBcGA1UEAwwQdGVzdC5leGFtcGxlLmNvbTEfMB0GCSqGSIb3
|
||||
DQEJARYQdGVzdEBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALZExtAsqspmBMot0/D1Ska36SaEEIZurdgh5odE2jcKWubJQegu4tAu
|
||||
Eq8LbL6bw8qmJZ6txp3fknIK3RjSyT39Rk0KtpGvrVjFPLAD42UNr8fVspPDHUR9
|
||||
yUvSpXoDxtcL6y6pn08jNnBFHkSnQK9br5wiNXWhSDkRTKfJ6Jvc269dA1qcJ2jU
|
||||
S1k5TXULhZwwvjeTFKb9+xwRjdnLlyh4+WSUvwUMDFgXeKn1iQppZ0Oc+G4Xyq8W
|
||||
oViOwruNMT3iUN83I3wKk3NOkdbx/IxD87UB19mKdmV4X1Nlj+m+/gidDf2DmriM
|
||||
FtnPp3kPaqwWBB+rV4AggwnKAOwfmUECAwEAAaNTMFEwHQYDVR0OBBYEFLR1jHET
|
||||
y8qVyFzsD9Ui0466XsLqMB8GA1UdIwQYMBaAFLR1jHETy8qVyFzsD9Ui0466XsLq
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIllEMRCi/n6bqfv
|
||||
3eMuzHBxvUNNjmTIbEfnPyjf81FB78e1V3mXE5cYcVbDOwbvzZKa6qcioG88iW8Y
|
||||
5b9RnLQjy9os7xhne1BJq3J2B6XKlHv9O1f5x1fb6nZ/8m7XyGmXctIGs3K29/sF
|
||||
zFqx7UgSujZCtKannnjS7RCMTbCixhxVbgwBRSkTLBxNWssHaJ7q4ktrfKdXSHAm
|
||||
BhfgrvbILYYYN38i7Hfwru7m6Uoo7I+sy8yfHZzm3DwvswVRpRFIWLtkc6PBbyE4
|
||||
xXWjoJrbFGyzSdLg+DX5SpJ4569Jueuj2LiDCsJ3r1whlUO/gDfB3jdrrUrkxrBq
|
||||
mmW22K8=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2RMbQLKrKZgTK
|
||||
LdPw9UpGt+kmhBCGbq3YIeaHRNo3ClrmyUHoLuLQLhKvC2y+m8PKpiWercad35Jy
|
||||
Ct0Y0sk9/UZNCraRr61YxTywA+NlDa/H1bKTwx1EfclL0qV6A8bXC+suqZ9PIzZw
|
||||
RR5Ep0CvW6+cIjV1oUg5EUynyeib3NuvXQNanCdo1EtZOU11C4WcML43kxSm/fsc
|
||||
EY3Zy5coePlklL8FDAxYF3ip9YkKaWdDnPhuF8qvFqFYjsK7jTE94lDfNyN8CpNz
|
||||
TpHW8fyMQ/O1AdfZinZleF9TZY/pvv4InQ39g5q4jBbZz6d5D2qsFgQfq1eAIIMJ
|
||||
ygDsH5lBAgMBAAECggEAC732iOa3wf48hMHbC4Th2hhy/rY3UlHDBU95yHEZFb6n
|
||||
CIMiqdCLcBnnvjsgME9cl6uIdOaBCx6iEpK8l6LMsB+m7cOo603D/xoFxNkbRyFQ
|
||||
l7EepgJF2mm4FBhn7KpdnvD3n7PxvWlpUmZBgu67bhCcCZTymLdhLbv9kjmhsJi3
|
||||
qqlygaWUaj91yQFLJ4PeTnTMRd4yVFvP9IDGxgTQzDzlMQz1uAu52dunB+TkLkJI
|
||||
/MgbhC5/bAWmgqgmbNjhFkQgwdG787jstXtMvLBGnYNhBVzuqr4XHh31pKFhl+z3
|
||||
hG1Hi3yg+XzKVSS7wb+qMv38dGVZYSTSa06vs03mWQKBgQD8cbcGu52iFi1h/9xY
|
||||
ge1EmIiT9SrYIaYhzrPFdzeY7jpaXfXYZ+nPyrTs6nRxW/RsHP1YxM5WUTE23zhL
|
||||
g9W1NWATHKh1n+QAwHQdYZWJN1LyqCW5q3fl0koAQGuXIMqKpv3PR+4pyhxdGNC9
|
||||
MnPTLQmWkIMA7RBAizNN3aXaYwKBgQC41gRDf1Zv/Wg2kc8u3hOX0tbuT9bxium3
|
||||
kfXmDEJUQ9fww8rA9ZKo3weKMvUklmrXEbLjMN2Md8hmdBVHQXXhtXyZzoiCHVct
|
||||
DNW2TvqBxpJCnLA3bHr8fgPSAHs7SGAM8gF5mY9ZhPI4+Drjk6YlOHVcEr82C1nG
|
||||
jJbCdVYdCwKBgFdO1OglNy150hRUs1aBCRhyULorTrgVWynSHWasBrSDn/blDEPe
|
||||
HIVbLBvMMp2KGgzSMeTjnCFKT2UU6pljbSQQ47t4a+LSe76u0PngaCFe2vdFpFaE
|
||||
sSDxC9rubMeF9cbiXmG0FPCrEAg6rubgbiKZLvm93TESzE4mVoYVpGjVAoGBAKrG
|
||||
0tmqZarDb+47ejnLZj74xy0ZB3fU6Wx6p8ANw5sns/T4cfUm8IKmzsiZnHZZpA1i
|
||||
hO300D5gzgAbcS2NBeWtUZqqgOX3RfyRx0PSZRJS7gAt1YLf8CIqLE1ztGhpzpUn
|
||||
ZMV9ZD1J4KNSdtaeLPxm1chkadb9Vc1lSEYTM6VRAoGAIcA1aEllKEOWXeZAUfny
|
||||
l67WA0ua6ss2dPQWJumflcf73jajE+jZQagsnRIJv34jJaP/O5A5OKU1WnemKlVU
|
||||
fyBd4R4nr47yCLxk2HNwUQBluG6EIeUbdEM/2P6qAamIG4FzurvTKIZ7h2dgvtME
|
||||
RaRkhB6Q8tXUwjQ+HfCpw9Q=
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtkTG0CyqymYEyi3T8PVK
|
||||
RrfpJoQQhm6t2CHmh0TaNwpa5slB6C7i0C4SrwtsvpvDyqYlnq3Gnd+ScgrdGNLJ
|
||||
Pf1GTQq2ka+tWMU8sAPjZQ2vx9Wyk8MdRH3JS9KlegPG1wvrLqmfTyM2cEUeRKdA
|
||||
r1uvnCI1daFIORFMp8nom9zbr10DWpwnaNRLWTlNdQuFnDC+N5MUpv37HBGN2cuX
|
||||
KHj5ZJS/BQwMWBd4qfWJCmlnQ5z4bhfKrxahWI7Cu40xPeJQ3zcjfAqTc06R1vH8
|
||||
jEPztQHX2Yp2ZXhfU2WP6b7+CJ0N/YOauIwW2c+neQ9qrBYEH6tXgCCDCcoA7B+Z
|
||||
QQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sf="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd" targetNamespace="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd" elementFormDefault="qualified">
|
||||
<import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd"/>
|
||||
<import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig/xmldsig-core-schema.xsd"/>
|
||||
<complexType name="CabeceraType">
|
||||
<annotation>
|
||||
<documentation xml:lang="es"> Datos de cabecera </documentation>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,318 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE schema
|
||||
PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
|
||||
[
|
||||
<!ATTLIST schema
|
||||
xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
|
||||
<!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
|
||||
<!ENTITY % p ''>
|
||||
<!ENTITY % s ''>
|
||||
]>
|
||||
|
||||
<!-- Schema for XML Signatures
|
||||
http://www.w3.org/2000/09/xmldsig#
|
||||
$Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
|
||||
|
||||
Copyright 2001 The Internet Society and W3C (Massachusetts Institute
|
||||
of Technology, Institut National de Recherche en Informatique et en
|
||||
Automatique, Keio University). All Rights Reserved.
|
||||
http://www.w3.org/Consortium/Legal/
|
||||
|
||||
This document is governed by the W3C Software License [1] as described
|
||||
in the FAQ [2].
|
||||
|
||||
[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
|
||||
[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
|
||||
-->
|
||||
|
||||
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
||||
targetNamespace="http://www.w3.org/2000/09/xmldsig#"
|
||||
version="0.1" elementFormDefault="qualified">
|
||||
|
||||
<!-- Basic Types Defined for Signatures -->
|
||||
|
||||
<simpleType name="CryptoBinary">
|
||||
<restriction base="base64Binary">
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<!-- Start Signature -->
|
||||
|
||||
<element name="Signature" type="ds:SignatureType"/>
|
||||
<complexType name="SignatureType">
|
||||
<sequence>
|
||||
<element ref="ds:SignedInfo"/>
|
||||
<element ref="ds:SignatureValue"/>
|
||||
<element ref="ds:KeyInfo" minOccurs="0"/>
|
||||
<element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="SignatureValue" type="ds:SignatureValueType"/>
|
||||
<complexType name="SignatureValueType">
|
||||
<simpleContent>
|
||||
<extension base="base64Binary">
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<!-- Start SignedInfo -->
|
||||
|
||||
<element name="SignedInfo" type="ds:SignedInfoType"/>
|
||||
<complexType name="SignedInfoType">
|
||||
<sequence>
|
||||
<element ref="ds:CanonicalizationMethod"/>
|
||||
<element ref="ds:SignatureMethod"/>
|
||||
<element ref="ds:Reference" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
|
||||
<complexType name="CanonicalizationMethodType" mixed="true">
|
||||
<sequence>
|
||||
<any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<!-- (0,unbounded) elements from (1,1) namespace -->
|
||||
</sequence>
|
||||
<attribute name="Algorithm" type="anyURI" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<element name="SignatureMethod" type="ds:SignatureMethodType"/>
|
||||
<complexType name="SignatureMethodType" mixed="true">
|
||||
<sequence>
|
||||
<element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
|
||||
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<!-- (0,unbounded) elements from (1,1) external namespace -->
|
||||
</sequence>
|
||||
<attribute name="Algorithm" type="anyURI" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<!-- Start Reference -->
|
||||
|
||||
<element name="Reference" type="ds:ReferenceType"/>
|
||||
<complexType name="ReferenceType">
|
||||
<sequence>
|
||||
<element ref="ds:Transforms" minOccurs="0"/>
|
||||
<element ref="ds:DigestMethod"/>
|
||||
<element ref="ds:DigestValue"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
<attribute name="URI" type="anyURI" use="optional"/>
|
||||
<attribute name="Type" type="anyURI" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="Transforms" type="ds:TransformsType"/>
|
||||
<complexType name="TransformsType">
|
||||
<sequence>
|
||||
<element ref="ds:Transform" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<element name="Transform" type="ds:TransformType"/>
|
||||
<complexType name="TransformType" mixed="true">
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<any namespace="##other" processContents="lax"/>
|
||||
<!-- (1,1) elements from (0,unbounded) namespaces -->
|
||||
<element name="XPath" type="string"/>
|
||||
</choice>
|
||||
<attribute name="Algorithm" type="anyURI" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<!-- End Reference -->
|
||||
|
||||
<element name="DigestMethod" type="ds:DigestMethodType"/>
|
||||
<complexType name="DigestMethodType" mixed="true">
|
||||
<sequence>
|
||||
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="Algorithm" type="anyURI" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<element name="DigestValue" type="ds:DigestValueType"/>
|
||||
<simpleType name="DigestValueType">
|
||||
<restriction base="base64Binary"/>
|
||||
</simpleType>
|
||||
|
||||
<!-- End SignedInfo -->
|
||||
|
||||
<!-- Start KeyInfo -->
|
||||
|
||||
<element name="KeyInfo" type="ds:KeyInfoType"/>
|
||||
<complexType name="KeyInfoType" mixed="true">
|
||||
<choice maxOccurs="unbounded">
|
||||
<element ref="ds:KeyName"/>
|
||||
<element ref="ds:KeyValue"/>
|
||||
<element ref="ds:RetrievalMethod"/>
|
||||
<element ref="ds:X509Data"/>
|
||||
<element ref="ds:PGPData"/>
|
||||
<element ref="ds:SPKIData"/>
|
||||
<element ref="ds:MgmtData"/>
|
||||
<any processContents="lax" namespace="##other"/>
|
||||
<!-- (1,1) elements from (0,unbounded) namespaces -->
|
||||
</choice>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="KeyName" type="string"/>
|
||||
<element name="MgmtData" type="string"/>
|
||||
|
||||
<element name="KeyValue" type="ds:KeyValueType"/>
|
||||
<complexType name="KeyValueType" mixed="true">
|
||||
<choice>
|
||||
<element ref="ds:DSAKeyValue"/>
|
||||
<element ref="ds:RSAKeyValue"/>
|
||||
<any namespace="##other" processContents="lax"/>
|
||||
</choice>
|
||||
</complexType>
|
||||
|
||||
<element name="RetrievalMethod" type="ds:RetrievalMethodType"/>
|
||||
<complexType name="RetrievalMethodType">
|
||||
<sequence>
|
||||
<element ref="ds:Transforms" minOccurs="0"/>
|
||||
</sequence>
|
||||
<attribute name="URI" type="anyURI"/>
|
||||
<attribute name="Type" type="anyURI" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<!-- Start X509Data -->
|
||||
|
||||
<element name="X509Data" type="ds:X509DataType"/>
|
||||
<complexType name="X509DataType">
|
||||
<sequence maxOccurs="unbounded">
|
||||
<choice>
|
||||
<element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
|
||||
<element name="X509SKI" type="base64Binary"/>
|
||||
<element name="X509SubjectName" type="string"/>
|
||||
<element name="X509Certificate" type="base64Binary"/>
|
||||
<element name="X509CRL" type="base64Binary"/>
|
||||
<any namespace="##other" processContents="lax"/>
|
||||
</choice>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="X509IssuerSerialType">
|
||||
<sequence>
|
||||
<element name="X509IssuerName" type="string"/>
|
||||
<element name="X509SerialNumber" type="integer"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- End X509Data -->
|
||||
|
||||
<!-- Begin PGPData -->
|
||||
|
||||
<element name="PGPData" type="ds:PGPDataType"/>
|
||||
<complexType name="PGPDataType">
|
||||
<choice>
|
||||
<sequence>
|
||||
<element name="PGPKeyID" type="base64Binary"/>
|
||||
<element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>
|
||||
<any namespace="##other" processContents="lax" minOccurs="0"
|
||||
maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<sequence>
|
||||
<element name="PGPKeyPacket" type="base64Binary"/>
|
||||
<any namespace="##other" processContents="lax" minOccurs="0"
|
||||
maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
</choice>
|
||||
</complexType>
|
||||
|
||||
<!-- End PGPData -->
|
||||
|
||||
<!-- Begin SPKIData -->
|
||||
|
||||
<element name="SPKIData" type="ds:SPKIDataType"/>
|
||||
<complexType name="SPKIDataType">
|
||||
<sequence maxOccurs="unbounded">
|
||||
<element name="SPKISexp" type="base64Binary"/>
|
||||
<any namespace="##other" processContents="lax" minOccurs="0"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- End SPKIData -->
|
||||
|
||||
<!-- End KeyInfo -->
|
||||
|
||||
<!-- Start Object (Manifest, SignatureProperty) -->
|
||||
|
||||
<element name="Object" type="ds:ObjectType"/>
|
||||
<complexType name="ObjectType" mixed="true">
|
||||
<sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<any namespace="##any" processContents="lax"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
<attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
|
||||
<attribute name="Encoding" type="anyURI" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="Manifest" type="ds:ManifestType"/>
|
||||
<complexType name="ManifestType">
|
||||
<sequence>
|
||||
<element ref="ds:Reference" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="SignatureProperties" type="ds:SignaturePropertiesType"/>
|
||||
<complexType name="SignaturePropertiesType">
|
||||
<sequence>
|
||||
<element ref="ds:SignatureProperty" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<element name="SignatureProperty" type="ds:SignaturePropertyType"/>
|
||||
<complexType name="SignaturePropertyType" mixed="true">
|
||||
<choice maxOccurs="unbounded">
|
||||
<any namespace="##other" processContents="lax"/>
|
||||
<!-- (1,1) elements from (1,unbounded) namespaces -->
|
||||
</choice>
|
||||
<attribute name="Target" type="anyURI" use="required"/>
|
||||
<attribute name="Id" type="ID" use="optional"/>
|
||||
</complexType>
|
||||
|
||||
<!-- End Object (Manifest, SignatureProperty) -->
|
||||
|
||||
<!-- Start Algorithm Parameters -->
|
||||
|
||||
<simpleType name="HMACOutputLengthType">
|
||||
<restriction base="integer"/>
|
||||
</simpleType>
|
||||
|
||||
<!-- Start KeyValue Element-types -->
|
||||
|
||||
<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
|
||||
<complexType name="DSAKeyValueType">
|
||||
<sequence>
|
||||
<sequence minOccurs="0">
|
||||
<element name="P" type="ds:CryptoBinary"/>
|
||||
<element name="Q" type="ds:CryptoBinary"/>
|
||||
</sequence>
|
||||
<element name="G" type="ds:CryptoBinary" minOccurs="0"/>
|
||||
<element name="Y" type="ds:CryptoBinary"/>
|
||||
<element name="J" type="ds:CryptoBinary" minOccurs="0"/>
|
||||
<sequence minOccurs="0">
|
||||
<element name="Seed" type="ds:CryptoBinary"/>
|
||||
<element name="PgenCounter" type="ds:CryptoBinary"/>
|
||||
</sequence>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
|
||||
<complexType name="RSAKeyValueType">
|
||||
<sequence>
|
||||
<element name="Modulus" type="ds:CryptoBinary"/>
|
||||
<element name="Exponent" type="ds:CryptoBinary"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- End KeyValue Element-types -->
|
||||
|
||||
<!-- End Signature -->
|
||||
|
||||
</schema>
|
||||
Loading…
Reference in New Issue