carregarCertificado method

Future<void> carregarCertificado()
  • PFX/P12: Parse Pure Dart em todas as plataformas
  • PEM: Parse texto em todas as plataformas

Desktop com OpenSSL:

Se OpenSSL estiver disponível, tenta conversão automática PFX->PEM para melhor compatibilidade com certificados ICP-Brasil.

Implementation

Future<void> carregarCertificado() async {
  try {
    Uint8List certificadoBytes;

    // Obter bytes do certificado
    if (certificadoBase64 != null && certificadoBase64!.isNotEmpty) {
      // Certificado em Base64 (funciona em todas as plataformas!)
      certificadoBytes = _decodificarCertificadoBase64(certificadoBase64!);
    } else if (caminhoCertificado != null && caminhoCertificado!.isNotEmpty) {
      // Certificado em arquivo (Desktop/Mobile apenas)
      if (!FileIO.isSupported) {
        throw ExcecaoAssinaturaCertificado(
          '📱 Leitura de arquivo não suportada em Web.\n'
          'Use certificadoBase64 em vez de certificadoPath.',
        );
      }

      if (!await FileIO.fileExists(caminhoCertificado!)) {
        throw ExcecaoAssinaturaCertificado(
          'Certificado não encontrado: $caminhoCertificado',
        );
      }
      certificadoBytes = await FileIO.readFileAsBytes(caminhoCertificado!);
    } else {
      throw ExcecaoAssinaturaCertificado(
        'Nenhum certificado fornecido. Use certificadoBase64 ou caminhoCertificado.',
      );
    }

    // Detectar formato: PEM (texto) ou PKCS#12 (binário)
    final certificadoTexto = utf8.decode(
      certificadoBytes,
      allowMalformed: true,
    );
    final isPem =
        certificadoTexto.contains('-----BEGIN') &&
        certificadoTexto.contains('-----END');

    _DadosPkcs12 dadosCertificado;

    if (isPem) {
      //print('✅ Detectado formato PEM');
      dadosCertificado = _extrairDePem(certificadoTexto);
    } else {
      // PKCS#12/PFX
      //print('✅ Detectado formato PKCS#12/PFX');

      // Tentar conversão via OpenSSL em Desktop (melhor compatibilidade)
      if (FileIO.isDesktop && caminhoCertificado != null) {
        final pemConvertido = await FileIO.runOpenSSLConversion(
          caminhoCertificado!,
          senhaCertificado,
        );

        if (pemConvertido != null) {
          //print('✅ Convertido para PEM usando OpenSSL');
          dadosCertificado = _extrairDePem(pemConvertido);
        } else {
          // Fallback para parse Pure Dart
          //print('⚠️  OpenSSL não disponível, usando parser Pure Dart');
          dadosCertificado = _extrairPkcs12PureDart(
            certificadoBytes,
            senhaCertificado,
          );
        }
      } else {
        // Web/Mobile: usar parser Pure Dart diretamente
        dadosCertificado = _extrairPkcs12PureDart(
          certificadoBytes,
          senhaCertificado,
        );
      }
    }

    _chavePrivada = dadosCertificado.chavePrivada;
    _certificadoX509Base64 = dadosCertificado.certificado;
    _infoCertificado = dadosCertificado.info;

    if (!_infoCertificado!.isValido) {
      throw ExcecaoAssinaturaCertificado(
        'Certificado fora da validade. Válido de ${_infoCertificado!.validoDe} até ${_infoCertificado!.validoAte}',
      );
    }

    // print('✅ Certificado carregado: ${_infoCertificado!.nomeExibicao}');
    // print('   Válido até: ${_infoCertificado!.validoAte}');
    // print('   Dias restantes: ${_infoCertificado!.diasRestantes}');
  } catch (e) {
    if (e is ExcecaoAutenticaProcurador) rethrow;
    throw ExcecaoAssinaturaCertificado('Erro ao carregar certificado: $e');
  }
}