Overview
The Certificate Revocation method allows you to notify SIAT when a digital certificate has been compromised or is no longer valid. This is a critical security procedure that ensures future digital signatures associated with the revoked certificate are not processed.
Method Signature
func ( s * SiatCodigosService ) NotificaCertificadoRevocado (
ctx context . Context ,
config config . Config ,
request models . NotificaCertificadoRevocadoRequest ,
) ( * soap . EnvelopeResponse [ codigos . NotificaCertificadoRevocadoResponse ], error )
Building the Request
Use the builder pattern to construct a certificate revocation notification:
import " time "
revocationDate := time . Now ()
request := models . Codigos . NewNotificaCertificadoRevocadoRequest ().
WithCodigoAmbiente ( 1 ).
WithCodigoSistema ( "SystemCode123" ).
WithCodigoSucursal ( 0 ).
WithCuis ( "CUIS-CODE-HERE" ).
WithNit ( 1234567890 ).
WithCertificado ( "BASE64-ENCODED-CERTIFICATE" ).
WithRazonRevocacion ( "Certificate compromised due to security breach" ).
WithFechaRevocacion ( & revocationDate ).
Build ()
Request Parameters
Environment code:
1 - Production
2 - Testing/Development
System identification code assigned by SIAT
Branch office code where the certificate was used
Valid CUIS code for authentication
Company’s tax identification number
Base64-encoded digital certificate that is being revoked
Reason for the certificate revocation. Should clearly explain why the certificate is being revoked
Date and time when the certificate was revoked
Response Structure
type NotificaCertificadoRevocadoResponse struct {
RespuestaNotificaRevocado RespuestaNotificaRevocado
}
type RespuestaNotificaRevocado struct {
MensajesList [] MensajeServicio
Transaccion bool
}
type MensajeServicio struct {
Codigo int
Descripcion string
}
Response Fields
Indicates if the revocation notification was successfully processed:
true - Certificate revocation recorded successfully
false - Revocation notification failed
List of messages with confirmation or error details
Example Usage
package main
import (
" context "
" encoding/base64 "
" fmt "
" log "
" os "
" time "
" github.com/ron86i/go-siat/pkg/client "
" github.com/ron86i/go-siat/pkg/config "
" github.com/ron86i/go-siat/pkg/models "
)
func main () {
// Initialize client
cfg := config . Config {
Token : "your-api-token" ,
BaseURL : "https://pilotosiatservicios.impuestos.gob.bo" ,
Ambiente : 1 ,
Sistema : "SystemCode123" ,
NIT : 1234567890 ,
}
siatClient , err := client . NewSiatClient ( cfg )
if err != nil {
log . Fatal ( err )
}
// Read the certificate file
certData , err := os . ReadFile ( "path/to/certificate.pem" )
if err != nil {
log . Fatalf ( "Failed to read certificate: %v " , err )
}
// Encode certificate to base64
certBase64 := base64 . StdEncoding . EncodeToString ( certData )
// Set revocation date
revocationDate := time . Now ()
// Build request
request := models . Codigos . NewNotificaCertificadoRevocadoRequest ().
WithCodigoAmbiente ( cfg . Ambiente ).
WithCodigoSistema ( cfg . Sistema ).
WithCodigoSucursal ( 0 ).
WithCuis ( "YOUR-VALID-CUIS-CODE" ).
WithNit ( cfg . NIT ).
WithCertificado ( certBase64 ).
WithRazonRevocacion ( "Certificate private key was compromised" ).
WithFechaRevocacion ( & revocationDate ).
Build ()
// Execute request
ctx := context . Background ()
resp , err := siatClient . Codigos . NotificaCertificadoRevocado ( ctx , request )
if err != nil {
log . Fatalf ( "Failed to notify certificate revocation: %v " , err )
}
// Check response
if resp . Body . Response . RespuestaNotificaRevocado . Transaccion {
fmt . Println ( "Certificate revocation notification successful" )
// Display confirmation messages
for _ , msg := range resp . Body . Response . RespuestaNotificaRevocado . MensajesList {
fmt . Printf ( " Message: %s (Code: %d ) \n " , msg . Descripcion , msg . Codigo )
}
} else {
fmt . Println ( "Certificate revocation notification failed" )
// Display error messages
for _ , msg := range resp . Body . Response . RespuestaNotificaRevocado . MensajesList {
fmt . Printf ( " Error %d : %s \n " , msg . Codigo , msg . Descripcion )
}
}
}
Practical Example: Automated Revocation Workflow
package main
import (
" context "
" encoding/base64 "
" fmt "
" time "
" github.com/ron86i/go-siat/pkg/client "
" github.com/ron86i/go-siat/pkg/models "
)
type CertificateManager struct {
siatClient * client . SiatClient
companyNIT int64
codigoSistema string
}
func ( cm * CertificateManager ) RevokeCertificate (
certData [] byte ,
reason string ,
branch int ,
cuis string ,
) error {
// Encode certificate
certBase64 := base64 . StdEncoding . EncodeToString ( certData )
// Current timestamp
revocationDate := time . Now ()
// Build revocation request
request := models . Codigos . NewNotificaCertificadoRevocadoRequest ().
WithCodigoAmbiente ( 1 ).
WithCodigoSistema ( cm . codigoSistema ).
WithCodigoSucursal ( branch ).
WithCuis ( cuis ).
WithNit ( cm . companyNIT ).
WithCertificado ( certBase64 ).
WithRazonRevocacion ( reason ).
WithFechaRevocacion ( & revocationDate ).
Build ()
// Send notification to SIAT
ctx := context . Background ()
resp , err := cm . siatClient . Codigos . NotificaCertificadoRevocado ( ctx , request )
if err != nil {
return fmt . Errorf ( "failed to send revocation notification: %w " , err )
}
// Check if notification was successful
if ! resp . Body . Response . RespuestaNotificaRevocado . Transaccion {
var errors [] string
for _ , msg := range resp . Body . Response . RespuestaNotificaRevocado . MensajesList {
errors = append ( errors , fmt . Sprintf ( " %d : %s " , msg . Codigo , msg . Descripcion ))
}
return fmt . Errorf ( "revocation notification rejected: %v " , errors )
}
return nil
}
// Usage example
func main () {
// Initialize certificate manager
siatClient , _ := client . NewSiatClient ( config . Config {
Token : "your-token" ,
BaseURL : "https://pilotosiatservicios.impuestos.gob.bo" ,
})
cm := & CertificateManager {
siatClient : siatClient ,
companyNIT : 1234567890 ,
codigoSistema : "SystemCode123" ,
}
// Scenario: Certificate key was compromised
certData := [] byte ( "...certificate data..." )
err := cm . RevokeCertificate (
certData ,
"Private key exposed in security incident on 2024-01-15" ,
0 , // Branch 0
"CUIS-CODE" ,
)
if err != nil {
fmt . Printf ( "Failed to revoke certificate: %v \n " , err )
} else {
fmt . Println ( "Certificate successfully revoked and SIAT notified" )
}
}
Common Revocation Reasons
When notifying SIAT about certificate revocation, use clear and specific reasons:
“Private key compromised in security breach on [date]”
“Certificate credentials exposed in system logs”
“Unauthorized access to certificate storage detected”
“Employee with certificate access terminated”
Administrative Reasons
“Certificate replaced due to expiration”
“Business restructuring - new certificate issued”
“Certificate lost or destroyed”
“Migration to new certificate authority”
Technical Reasons
“Certificate algorithm no longer secure”
“Certificate format incompatible with updated systems”
“Duplicate certificate issued by error”
Best Practices
Immediate notification required : When you discover a certificate has been compromised, notify SIAT immediately to prevent unauthorized use.
Document the incident : Keep detailed records of why certificates were revoked, including dates, personnel involved, and circumstances. This helps with audits and compliance.
Have backup certificates ready : Before revoking a certificate, ensure you have a replacement certificate ready to avoid service disruptions.
Cannot be undone : Certificate revocation is permanent. Once notified, the certificate cannot be reactivated. Ensure you’re revoking the correct certificate.
SIAT typically accepts certificates in these formats:
PEM (Privacy Enhanced Mail)
DER (Distinguished Encoding Rules)
P7B/PKCS#7
PFX/P12/PKCS#12
Encoding the Certificate
import (
" encoding/base64 "
" os "
)
// Read and encode PEM certificate
func encodeCertificate ( certPath string ) ( string , error ) {
certData , err := os . ReadFile ( certPath )
if err != nil {
return "" , err
}
// Encode to base64
return base64 . StdEncoding . EncodeToString ( certData ), nil
}
// Usage
certBase64 , err := encodeCertificate ( "certificate.pem" )
if err != nil {
log . Fatal ( err )
}
Error Handling
Common Error Scenarios
If SIAT rejects the certificate format:
Verify the certificate is properly base64 encoded
Ensure the certificate file isn’t corrupted
Check that you’re sending the full certificate chain if required
Certificate Not Found
If SIAT reports the certificate doesn’t exist:
Verify the certificate was previously registered with SIAT
Check that you’re using the correct NIT and branch
Ensure the certificate matches your company’s records
Already Revoked
If the certificate was already revoked:
SIAT will reject duplicate revocation attempts
This is informational and doesn’t require action
Update your internal records if needed
Comprehensive Error Handling
func handleRevocationResponse (
resp * soap . EnvelopeResponse [ codigos . NotificaCertificadoRevocadoResponse ],
) error {
if ! resp . Body . Response . RespuestaNotificaRevocado . Transaccion {
// Parse error messages
for _ , msg := range resp . Body . Response . RespuestaNotificaRevocado . MensajesList {
switch msg . Codigo {
case 1 :
return nil // Success message
case 995 :
return fmt . Errorf ( "certificate not found: %s " , msg . Descripcion )
case 996 :
return fmt . Errorf ( "certificate already revoked: %s " , msg . Descripcion )
case 997 :
return fmt . Errorf ( "invalid certificate format: %s " , msg . Descripcion )
default :
return fmt . Errorf ( "revocation failed (code %d ): %s " ,
msg . Codigo , msg . Descripcion )
}
}
}
return nil
}
Security Considerations
Protect certificate data : When handling certificates in your code, ensure they’re transmitted securely and not logged or exposed in error messages.
Secure Certificate Handling
import (
" crypto/sha256 "
" encoding/hex "
" fmt "
)
// Log certificate revocation without exposing certificate data
func logCertificateRevocation ( certData [] byte , reason string ) {
// Create hash of certificate for logging
hash := sha256 . Sum256 ( certData )
certHash := hex . EncodeToString ( hash [:])
// Safe to log the hash
fmt . Printf ( "Revoking certificate with hash: %s \n " , certHash )
fmt . Printf ( "Reason: %s \n " , reason )
// Never log the actual certificate data
}
Post-Revocation Actions
After successfully revoking a certificate:
Update internal systems : Mark the certificate as revoked in your database
Deploy replacement certificate : Install and activate the new certificate
Test new certificate : Verify all systems work with the replacement
Notify stakeholders : Inform relevant team members of the change
Update documentation : Record the revocation in your compliance documentation
Destroy old certificate : Securely delete the revoked certificate’s private key
CUIS Request Request CUIS codes (required for revocation)
XML Signing Learn about digital signatures and certificates