The initializePkiConfigPath method was using a variable named
'instanceId' from getSystemValue('instanceid') which could be confused
with LibreSign's instance_id. Changed to 'systemInstanceId' for clarity
and consistency with getConfigPathByParams method.
This ensures the PKI directories are created in the correct appdata path
using Nextcloud's system instance ID, while the directory name itself
contains LibreSign's CA identifier with its own instance ID.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The CA ID (libresign-ca-id:...) in OrganizationalUnit should only be
filtered out when the certificate is not generated (isSetupOk() returns
false). When the certificate is successfully generated, the CA ID must
be preserved in the API response.
This ensures:
- Generated certificates: CA ID is visible (expected behavior)
- Failed/not generated: CA ID is filtered to prevent stale data in form
Integration tests validated:
- features/account/signature.feature:2 (OpenSSL)
- features/account/signature.feature:23 (CFSSL)
- features/admin/certificate_openssl.feature:2
- features/admin/certificate_openssl.feature:35
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Filter configPath from API response when certificate is not generated to prevent
form pre-population with outdated generation numbers that cause validation errors.
Filter CA ID (libresign-ca-id:*) from OrganizationalUnit field to prevent users
from submitting stale generation values that conflict with certificate validation.
Refactor toArray() method by extracting logic into dedicated methods:
- getConfigPathForApi(): Returns empty string for non-generated certificates
- removeCaIdFromOrganizationalUnit(): Filters CA IDs from OU arrays
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
When switching from OpenSSL to CFSSL engine without configuring CFSSL,
the configure-check was incorrectly showing 'success' status instead of
'error'. This happened because isSetupOk() only checked for ca.pem and
ca-key.pem files, which are common to both engines and shared in the
same config_path directory.
Now isSetupOk() also verifies the presence of CFSSL-specific files
(csr_server.json and config_server.json) to ensure it's a valid CFSSL
configuration and not just leftover OpenSSL files.
This fix ensures the certificate_engine_switch integration test passes.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add setEngine() method to IEngineHandler interface and implement
in AEngineHandler to automatically configure identify methods based
on certificate engine selection.
When engine is 'none', only account identification is enabled since
no certificate infrastructure is available for other methods.
Related to #5145
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Implement DocMdpHandler to validate PDF Document Modification Detection and Prevention (DocMDP)
- Add allowsAdditionalSignatures() method to check if PDF permits additional signatures
- Support detection of DocMDP level 1 (no changes allowed) certification
- Parse PDF signature dictionaries and transformation parameters
- Prevent signatures on DocMDP level 1 certified documents per PDF specification
- Enable compliance with PDF document certification and signature workflows
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add public method to check if DocMDP level allows additional signatures.
Returns false only for CERTIFIED_NO_CHANGES_ALLOWED (level 1).
Required for FileService to validate signature requests against DocMDP policy.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMDP support to JSignPdf signing process:
- Inject DocMdpConfigService to access admin configuration
- Add getCertificationLevel() to retrieve enabled level name
- Append -cl parameter to JSignParam when DocMDP is enabled
- Uses enum->name directly for JSignPdf compatibility
When DocMDP is enabled, JSignPdf will certify PDFs with configured level:
NOT_CERTIFIED, CERTIFIED_NO_CHANGES_ALLOWED, CERTIFIED_FORM_FILLING,
or CERTIFIED_FORM_FILLING_AND_ANNOTATIONS.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add validation to prevent empty Common Name (CN) in OpenSslHandler and CfsslHandler
- Throw EmptyCertificateException with clear message when CN is empty
- Fix JSignPdfHandlerTest to use valid commonName 'Test Root CA'
- Add unit test to verify empty CN validation works correctly
The owner field in libresign_crl table is mandatory without default value.
Previously, generateRootCert('') would fail at database level with unclear
error. Now it fails early with proper validation message.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Create dedicated handler for DocMDP (Document Modification Detection and Prevention)
- Implement extractDocMdpData() as single public API
- Add private methods for level extraction, modification detection, and validation
- Support all DocMDP levels with proper validation logic
- Clean architecture with minimal dependencies (only IL10N required)
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add IL10N dependency injection for translations
- Replace const ALLOWED_VARIABLES with instance property
- Add initializeVariablesMetadata() method with full metadata
- Add getVariablesMetadata() method returning associative array
- Include type, description, example, and optional default for each variable
- Add defaults for signedBy, linkToSite, and validateIn variables
- Update tests with IL10N mock and comprehensive coverage
- Add DataProviders for testing defaults and types
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Extract default template loading into a separate public method
to allow other services to access the default template content.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Expose getTemplate() method to allow external access to the
footer template logic (custom or default).
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Replace raw array with TemplateVariables class for better type safety
and explicit contract of available template variables.
Changes:
- Use TemplateVariables instance instead of array
- Replace array access with typed getters/setters
- Maintain backward compatibility via setTemplateVar()
- Improved code readability with explicit method names
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Introduces a type-safe collection class for footer template variables
using magic methods (__call) with runtime type validation.
Benefits:
- Whitelist of allowed variables with expected types
- Runtime type checking for all setters
- Fluent interface for method chaining
- Clean API with only ~70 lines of code
- Prevents invalid variables or type mismatches
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Only generate QR code if validationSite is available in templateVars.
This prevents undefined array key error when uuid is not set.
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Breaking changes:
- getFooter() now accepts only array $dimensions parameter
- UUID must be set via setTemplateVar('uuid', $uuid) before calling getFooter()
Changes:
- Remove FileEntity dependency from getFooter() signature
- Allow customization of all template variables via setTemplateVar()
- Only fetch default values from appConfig if not already customized
- Check if 'uuid' exists in templateVars before building validationSite
Benefits:
- Reduced coupling - no dependency on FileEntity
- More flexible - all variables customizable via same API
- Cleaner design - consistent use of setTemplateVar() for all variables
- Easier testing - no need to mock FileEntity
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Remove $file property to reduce coupling
- Make getMetadata() public and accept File as parameter
- Change getFooter() to receive dimensions array instead of File
- This allows more flexibility and reduces dependencies
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
When processing PDF signatures, hex2bin() and stream_get_contents()
can fail and return false when dealing with corrupted or malformed
signature data. Previously, this would cause a TypeError when false
was passed to processSignature() which expects ?string.
Now, invalid signatures are properly reported to users with a
'Digest Mismatch' validation error instead of causing a fatal error.
This fix:
- Validates hex2bin() return value before yielding
- Validates stream_get_contents() return value before processing
- Returns null for corrupted signatures which are then reported as invalid
- Suppresses expected hex2bin() warnings for non-hexadecimal data
Fixes the issue reported where users encountered:
TypeError: Argument #2 ($signature) must be of type ?string, false given
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Pass CertificateType::ROOT->value for root certificate generation
- Pass CertificateType::LEAF->value for user certificate generation
- Include issuer and subject DN data in serial number generation
- Ensure proper enum to string conversion for database storage
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Return early without throwing exception if ca.pem doesn't exist
- Return early if certificate file is empty
- Only validate when a proper root certificate is actually configured
- Fixes Pkcs7HandlerTest and Pkcs12HandlerTest that run without CA setup
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Return early if configPath is empty (test environments without CA)
- Still throw exception if CA path exists but certificate is missing/empty
- Prevents validation errors in unit tests without breaking production validation
- Fixes Pkcs7HandlerTest and Pkcs12HandlerTest failures
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add beforeSign() hook in SignEngineHandler base class
- Automatically validate root certificate in all sign() implementations
- Apply to JSignPdfHandler, Pkcs12Handler, and Pkcs7Handler
- Encapsulate validation logic within sign engine handlers
- Prevent signing with revoked/expired root certificates
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Call validateRootCertificate() in OpenSslHandler::generateCertificate()
- Call validateRootCertificate() in CfsslHandler::generateCertificate()
- Prevent issuing certificates from revoked/expired root CA
- Ensure root CA has sufficient validity to sign CRLs for issued certs
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add validateRootCertificate() method to check certificate health
- Verify certificate is not revoked via CRL
- Verify certificate has not expired
- Check if renewal is needed based on remaining validity
- Calculate renewal timing: remaining_days <= leaf_expiry_days
- Log warnings when renewal is recommended
- Throw LibresignException with clear messages on critical issues
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>