CURSO DE INFRAESTRUTURA DE CHAVES PÚBLICAS
Ciência da Computação - Universidade de Brasília
Professor Pedro Antonio Dourado de Rezende
TRABALHO FINAL
Autenticação de Usuários e Controle de Acesso
com Certificação Digital
Uma Implementação com OpenSSL
Gelson Heindrikson
José de Ribamar Campos de Sousa
31 de outubro de 2003
1. Escopo
1.1 Demonstrar o uso de certificados digitais para autenticação e controle de acesso de usuários;
2.1 Gerar um programa servidor para essa finalidade;
2.2 Gerar um programa cliente para essa finalidade;
2.3 Testar a implementação utilizando browsers para acessar o programa servidor;
2.4 Testar a implementação utilizando o programa cliente para acessar o programa servidor.
2. Referências
- Página Oficial do projeto OpenSSL: http://www.openssl.org
- Usando OpenSSL - Uma implementação livre do protocolo SSL: http://www.pedro.jmrezende.com.br/trabs/hammurabi.htm
- An Introduction to OpenSSL Programming (Part I): http://www.rtfm.com/openssl-examples/part1.pdf
- An Introduction to OpenSSL Programming (Part II): http://www.rtfm.com/openssl-examples/part2.pdf
- Cygwin - a Linux-like environment for Windows: http://sources.redhat.com/cygwin
Obs.: Neste trabalho, foi utilizado um programa servidor criado a partir da adaptação do módulo servidor listado na referência 2 acima; já o programa cliente foi criado a partir de uma adaptação do módulo cliente listado na referência 3 acima.
3. Ambiente
A compilação e os testes foram efetuados no sistema operacional Conectiva Linux 9 e também com o Cygwin executando sob Windows XP e 2000. Possivelmente não requer modificações para compilar/executar sob outros sistemas operacionais UNIX-like.
4. Estrutura de diretórios
O arquivo de recursos (vide Apêndice A), contém todos os programas necessários para o leitor interessado em repetir os passos detalhados nesse roteiro. De forma resumida, o conteúdo está estruturado conforme abaixo:
/ca
/ca.config
/demoCA
/<diversos scripts *.sh para gerar chaves e certificados>
/cliente
/wclient.c
/<demais arquivos fontes *.c e *.h do programa cliente>
/servidor
/area1
/area2
/keys
/servidor.c
/<demais arquivos fontes *.c e *.h do programa servidor>
/<scripts *.sh para copiar certificados e chaves para os diretórios das aplicações cliente e servidor>
5. Arquivo "ca.config"
O arquivo "ca.config" foi adaptado a partir do original, que normalmente fica em /etc/ssl/openssl.cnf. As principais alterações foram para incluir OIDs específicos na extensão Extended Key Usage, que servirão para identificar o perfil de acesso do usuário cliente.
...
...
# FAKE OIDS CRIADOS A PARTIR DO OBJ_ID_KP DA PKIX
OBJ_id_kp=1.3.6.1.5.5.7.3
fake_oid_user_type1=${OBJ_id_kp}.999
fake_oid_user_type2=${OBJ_id_kp}.998
...
...
[ cli_cert1 ]
...
#extended key usage para um usuario cliente type1
extendedKeyUsage = clientAuth, codeSigning, emailProtection, fake_oid_user_type1
...
...
[ cli_cert2 ]
...
#extended key usage para um usuario cliente type2
extendedKeyUsage = clientAuth, codeSigning, emailProtection, fake_oid_user_type2
6. Roteiro para criação de chaves e certificados
6.1 Criação da chave e certificado do CA
Sob o diretório "ca", executar o script 'geraca.sh', o qual irá executar os seguintes comandos:
openssl genrsa -des3 -out chave_privada_ca.pem 2048
cp chave_privada_ca.pem ./demoCA/private/cakey.pem
openssl req -new -x509 -config ca.config -key chave_privada_ca.pem -out certificado_ca.pem -days 365
cp certificado_ca.pem ./demoCA/cacert.pem
Observações:
Após execução desse script, a chave privada do CA estará no arquivo "chave_privada_ca.pem" e o certificado do CA estará no arquivo "certificado_ca.pem". Cópias desses arquivos também foram feitas, respectivamente em "./demoCA/private/cakey.pem" e "./demoCA/cacert.pem" (é onde o utilitário 'openssl' irá buscar tais dados quando o CA assinar certificados - conforme configurado em 'ca.config').
- para facilitar, quando for solicitada uma password, informe sempre a string "password".
- deixe os valores default para os campos 'Country', 'Locality', etc. Em 'CommonName' informe um nome de sua preferência para o CA.
6.2 Criação da chave e certificado do Servidor
Sob o diretório "ca", executar o script 'geraserv.sh', o qual irá executar os seguintes comandos:
openssl genrsa -des3 -out chave_privada_sv.pem 2048
openssl req -new -config ca.config -key chave_privada_sv.pem -out pedido_sv.pem
openssl ca -config ca.config -extensions usr_cert -out certificado_sv.pem -in pedido_sv.pem
Observações:
Após execução desse script a chave privada do Servidor estará no arquivo "chave_privada_sv.pem", e o certificado, assinado pelo CA, estará em "certificado_sv.pem".
- para facilitar, quando for solicitada uma password, informe sempre a string "password";
- deixe os valores default para os campos 'Country', 'Organization', 'Locality', 'Email', etc;
- no campo 'Common Name' informe "localhost", a fim de executar o servidor na própria máquina local;
- quando for solicitado "Enter pass phrase for ./demoCA/private/cakey.pem" informe "password", caso tenha sido esta a password configurada para o CA na seção 6.1;
- quando for solicitado "Sign the certificate? [y/n]:" e "1 out of 1 certificate requests certified, commit? [y/n]:" informe 'y' em ambas as respostas, para confirmar assinatura e geração do certificado.
6.3 Criação da chave e certificado do Cliente UM
Sob o diretório "ca", executar o script 'geracli1.sh', o qual irá executar os seguintes comandos:
openssl genrsa -des3 -out chave_privada_cli1.pem 2048
openssl req -new -config ca.config -key chave_privada_cli1.pem -out pedido_cli1.pem
openssl ca -config ca.config -extensions cli_cert1 -out certificado_cli1.pem -in pedido_cli1.pem
openssl pkcs12 -export -clcerts -in certificado_cli1.pem -inkey chave_privada_cli1.pem -out certificado_cli1.pfx
Observações:
Após execução desse script a chave privada do Cliente UM estará no arquivo "chave_privada_cli1.pem", e o certificado, assinado pelo CA, estará em "certificado_cli1.pem".
- o parâmetro -extensions cli_cert1 no terceiro comando acima informa ao openssl qual é a seção do arquivo 'ca.config' a ser usada para incluir extensões no certificado (no caso, é a seção cli_cert1);
- para facilitar, quando for solicitada uma password, informe sempre a string "password";
- deixe os valores default para os campos 'Country', 'Organization', 'Locality', 'Email'
- no campo 'Common Name' informe "Cliente UM";
- quando for solicitado "Enter pass phrase for ./demoCA/private/cakey.pem" informe "password", ou outra password configurada para o CA na seção 6.1;
- quando for solicitado "Sign the certificate? [y/n]:" e "1 out of 1 certificate requests certified, commit? [y/n]:" informe 'y' em ambas as respostas, para confirmar assinatura e geração do certificado;
- o quarto comando acima exporta o certificado E a chave privada em formato pkcs12.
6.4 Criação da chave e certificado do Cliente DOIS
Sob o diretório "ca", executar o script 'geracli2.sh', o qual irá executar os seguintes comandos:
openssl genrsa -des3 -out chave_privada_cli2.pem 2048
openssl req -new -config ca.config -key chave_privada_cli2.pem -out pedido_cli2.pem
openssl ca -config ca.config -extensions cli_cert2 -out certificado_cli2.pem -in pedido_cli2.pem
openssl pkcs12 -export -clcerts -in certificado_cli2.pem -inkey chave_privada_cli2.pem -out certificado_cli2.pfx
Observações:
Após execução desse script a chave privada do Cliente UM estará no arquivo "chave_privada_cli2.pem", e o certificado, assinado pelo CA, estará em "certificado_cli2.pem".
- o parâmetro -extensions cli_cert2 no terceiro comando acima informa ao openssl qual é a seção do arquivo 'ca.config' a ser usada para incluir extensões no certificado (no caso, é a seção cli_cert2);
- para facilitar, quando for solicitada uma password, informe sempre a string "password";
- deixe os valores default para os campos 'Country', 'Organization', 'Locality', 'Email', etc;
- no campo 'Common Name' informe "Cliente DOIS";
- quando for solicitado "Enter pass phrase for ./demoCA/private/cakey.pem" informe "password", ou outra password configurada para o CA na seção 6.1;
- quando for solicitado "Sign the certificate? [y/n]:" e "1 out of 1 certificate requests certified, commit? [y/n]:" informe 'y' em ambas as respostas, para confirmar assinatura e geração do certificado;
- o quarto comando acima exporta o certificado E a chave privada em formato pkcs12.
7. Alterações nos programas do módulo Servidor
7.1 Alterações no arquivo "utils.c"
Foi incluído a seguinte chamada, na função inicializar_contexto() para que o servidor solicite um certificado ao cliente durante o 'handshake' SSL:
/* solicita autenticacao do cliente */
SSL_CTX_set_verify(contexto,SSL_VERIFY_PEER,0);
Foi incluída a função pegar_dados_peer() abaixo, para pegar os dados do certificado do cliente:
/* Se o peer enviou certificado, pega o common-name e le todos obj-id que
compoem a extensao extended-key-usage, verifica se o obj-id tem o
prefixo que nós estamos esperando, copia para o buffer o obj-id com maior
valor, em formato string. Retorna -1 se peer nao enviou certificado */
int pegar_dados_peer(SSL *ssl, char *str_exku, int tam1, char *cn_peer, int tam2){
char temp_buf[32] = "";
X509 *peer;
EXTENDED_KEY_USAGE *extusage;
ASN1_OBJECT *obj;
int idx;
memset(str_exku,0,tam1);
memset(cn_peer,0,tam2);
printf("Vou pegar certificado do peer\n");
peer=SSL_get_peer_certificate(ssl);
//pode ser null, pois foi solicitado, nao exigido:
if(peer == NULL) {
return -1;
}
/* pega o common-name do peer */
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, cn_peer, tam2);
/* pega o extended-key-usage com prefixo correto e maior valor */
printf("Iniciando loop para checar extended-key-usage\n");
if((extusage=X509_get_ext_d2i(peer, NID_ext_key_usage, NULL, NULL))) {
for(idx = 0; idx < sk_ASN1_OBJECT_num(extusage); idx++) {
obj = sk_ASN1_OBJECT_value(extusage,idx);
OBJ_obj2txt(temp_buf, sizeof(temp_buf), obj, 1);
printf("Encontrado objid= %s\n",temp_buf);
//ve se oid inicia com o prefixo desejado:
if(strstr(temp_buf, PREF_OID_CLI) == temp_buf) {
//printf("prefix match!\n");
//mantem no buffer de retorno a string com o maior valor:
if(strcmp(str_exku, temp_buf) < 0) {
//printf("str_exku e' menor, vou copiar\n");
strncpy(str_exku,temp_buf,tam1-1);
}
}
}
sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
}
//desaloca memoria!
X509_free(peer);
return 0;
}
7.1 Alterações no arquivo "servidor.c"
Foi incluída a função validar_acesso() abaixo, para validar o acesso ao recurso solicitado pelo cliente. Isso é feito chamando-se a função pegar_dados_peer()para ler o certificado do cliente, em seguida é verificada a extensão Extended Key Usage do certificado . Aos clientes que tem nesta extensão um OID_CLI_TYPE1 é dado acesso a qualquer arquivo sob a árvore de diretório "area1" do servidor. Já aos clientes com um OID_CLI_TYPE2 é dado acesso a qualquer arquivo sob a árvore de diretório "area2" do servidor.
Caso o cliente não apresente um certificado válido, é enviada uma página de erro ao cliente.
//Autentica cliente e verifica acesso ao arquivo solicitado,
//retorna em nome_arquivo_ret o proprio arquivo solicitado ou
//index ou pagina de erro, conforme o acesso do usuario.
//Pode retornar um header, conforme o caso.
void validar_acesso(SSL *ssl, char *inicio_nome_arquivo,
char *nome_arquivo_ret, int tam_nome, char *header) {
char cn_peer[32];
char ext_key_usage[32];
//char *desculpe ="<html><body style=\"background-color: rgb(255, 255, 204);\"><h2>Desculpe sr(a) usuario(a) %s,</h2><br></body></html>\r\n";
char *desculpe ="<html><body><h2>Desculpe sr(a) usuario(a) %s,</h2><br></body></html>\r\n";
//char *bemvindo ="<html><body style=\"background-color: rgb(156, 255, 255);\"><h2>Bemvindo sr(a) usuario(a) %s,</h2><br></body></html>\r\n";
char *bemvindo ="<html><body><h2>Bemvindo sr(a) usuario(a) %s,</h2><br></body></html>\r\n";
memset(ext_key_usage,0, sizeof(ext_key_usage));
/* pega extended key usage do peer, se enviou certif.*/
if(pegar_dados_peer(ssl, ext_key_usage, sizeof(ext_key_usage),
cn_peer, sizeof(cn_peer)) != -1 ) {
printf("CommonName do peer: %s\n", cn_peer);
printf("Extended key usage a ser usado: %s\n",ext_key_usage);
} else {
printf("Peer nao enviou certificado\n");
}
if(strcmp(ext_key_usage, OID_CLI_TYPE1) == 0) {
if( ! (strstr(inicio_nome_arquivo, AREA1) == inicio_nome_arquivo)) {
//esta' tentando acessar recurso fora da area permitida
//header[0] = '\0';
sprintf(header, desculpe, cn_peer);
strncpy(nome_arquivo_ret, "erro1.html", tam_nome);
} else { //acesso ao recurso ok
if(strstr(inicio_nome_arquivo, AREA1"/index1.html") != NULL ) {
sprintf(header, bemvindo, cn_peer); //esta pedindo o index, adiciona bemvindo
strncpy(nome_arquivo_ret, inicio_nome_arquivo, tam_nome);
} else {
header[0] = '\0';//esta pedindo um arquivo normal, nao ha header
strncpy(nome_arquivo_ret, inicio_nome_arquivo, tam_nome);
}
}
} else {
if(strcmp(ext_key_usage, OID_CLI_TYPE2) == 0) {
if( ! (strstr(inicio_nome_arquivo, AREA2) == inicio_nome_arquivo)) {
//esta' tentando acessar recurso fora da area permitida
sprintf(header, desculpe, cn_peer);
strncpy(nome_arquivo_ret, "erro2.html", tam_nome);
} else { //acesso ao recurso ok
if(strstr(inicio_nome_arquivo, AREA2"/index2.html") != NULL ) {
sprintf(header, bemvindo, cn_peer); //esta pedindo o index, adiciona bemvindo
strncpy(nome_arquivo_ret, inicio_nome_arquivo, tam_nome);
} else {
header[0] = '\0';//esta pedindo um arquivo normal, nao ha header
strncpy(nome_arquivo_ret, inicio_nome_arquivo, tam_nome);
}
}
}else { //nao possui nenhum dos OID acima ou nao enviou certificado
sprintf(header, desculpe, cn_peer);
strncpy(nome_arquivo_ret, "errocert.html", tam_nome);
}
}
printf("Arquivo a ser retornado: %s\n", nome_arquivo_ret);
return;
}
Se o cliente estiver solicitando um arquivo situado fora da sua área de acesso, é enviada uma mensagem de erro contendo um link para o menu de opções permitidas;
Se o cliente estiver solicitando o arquivo "index" dentro da sua área, é enviada uma saudação e o menu de opções;
Se o cliente estiver solicitando outro arquivo qualquer dentro da sua área de acesso, é enviado o conteúdo do arquivo.
Algumas páginas são montadas dinamicamente, de forma a incluir uma saudação contendo o Common Name do cliente, que foi lido do certificado. Para isso, foi alterada a assinatura da função transmitir_arquivo(), incluindo um parâmetro com um header (a saudação) a ser transmitido antes do conteúdo do arquivo:
int transmitir_arquivo(char *nome_arquivo, BIO *bio_buffer_ssl, char *header) {
e o seguinte trecho de código foi inserido naquela função:
if(strlen(header) != 0) { //adiciona o header antes de enviar o arquivo
if(BIO_puts(bio_buffer_ssl, header) <= 0) {
ERR_print_errors(bio_stderr);
return -1;
}
}
8. Alterações nos programas do módulo cliente
8.1 Alterações no arquivo "wclient.c"
O trecho abaixo foi modificado, para incluir as opções "-f" que receberá o nome do arquivo, e a opção "-j" que receberá um flag que informa se o programa cliente enviará ou não um certificado ao servidor.
while((c=getopt(argc,argv,"h:p:f:i:j"))!=-1){
switch(c){
O trecho abaixo foi alterado, para inicializar o contexto com ou sem um arquivo de chave/certificado:
case 'h':
if(!(host=strdup(optarg)))
err_exit("Out of memory (host)");
break;
case 'p':
if(!(port=atoi(optarg)))
err_exit("Bogus port specified");
break;
case 'f':
if(!(file=strdup(optarg)))
err_exit("Out of memory (file)");
break;
case 'i':
require_server_auth=0;
break;
case 'j':
require_client_auth=0;
break;
}
}
if(require_client_auth) {
ctx=initialize_ctx(KEYFILE,PASSWORD);
} else {
/* nao usaremos certificado do cliente: */
ctx=initialize_ctx(NULL,PASSWORD);
}
8.2 Alterações no arquivo "commons.c"
O segmento abaixo foi alterado, de forma que as funções SSL_CTX_use_certificate_chain_file() e SSL_CTX_use_PrivateKey_file()são usadas apenas quando um arquivo de chave/certificado foi informado:
/* se keyfile vazio, nao usaremos este arquivo */
if(keyfile != NULL) {
printf("Vou chamar use_certificate_chain_file em %s\n", keyfile);
if(!(SSL_CTX_use_certificate_chain_file(ctx, keyfile)))
berr_exit("Can't read certificate file");
}
pass=password;
/* se keyfile vazio, nao usaremos este arquivo */
if(keyfile != NULL) {
printf("Vou chamar use_PrivateKey_file em %s\n", keyfile);
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile,SSL_FILETYPE_PEM)))
berr_exit("Can't read key file");
}
9. Compilação dos módulos cliente e servidor
Os módulos servidor e cliente podem ser compilados, respectivamente, com os comandos abaixo:
No diretório 'servidor':
gcc -o servidor servidor.c utils.c -lssl -lcrypto
No diretório 'cliente':
gcc -o wclient wclient.c common.c read_write.c client.c -lcrypto -lssl
10. Roteiro para teste de acesso utilizando browser
10.1 Inicializando o servidor
Antes de executar o programa servidor é preciso rodar o script "gera_arquivos_servidor.sh", localizado na raiz do diretório do arquivo de recursos. Ele efetua uma cópia das chaves e certificados do CA e do Servidor para os locais esperados pelo programa:
# copia os arquivos necessarios ao funcionamento do
# programa 'servidor' para os diretorios corretos
cp ca/certificado_ca.pem servidor/keys/certificado_ca.pem
cp ca/certificado_sv.pem servidor/keys/certificado_sv.pem
cp ca/chave_privada_sv.pem servidor/keys/chave_privada_sv.pem
Feito isso, vá para o diretório 'servidor' e digite o comando abaixo, para inicializar o servidor na porta 9999:
./servidor 9999
Será solicitada a senha da chave privada do servidor: informe "password" ou outra utilizada na geração da chave privada do servidor (ver seção 6.2).
10.1 Importando o certificado do CA no Mozilla
Utilize o menu "Editar/Preferências" e selecione, dentro da categoria "Privacidade", a opção "Certificados", conforme a figura abaixo:
Clique no botão "Abrir" na seção "Gerenciador de Certificados", para que seja apresentada a tela seguinte:
Para importar o certificado do CA, selecione a aba "Autoridades" e clique no botão "Importar". Navegue até o diretório 'ca' dentro da estrutura de diretórios do arquivo de recursos e selecione o arquivo "certificado_ca.pem". Será apresentado o dialog a seguir:
Marque todas as finalidades listadas e clique em "OK" para concluir a importação do certificado do CA.
10.2 Acessando o servidor sem instalar um certificado de cliente
Ao tentarmos acessar uma URL válida no servidor (por exemplo: https://localhost:9999/utils.h), antes de instalarmos um certificado de cliente no browser, obteremos uma resposta semelhante à abaixo:
10.3 Importando o certificado do Cliente UM no Mozilla
Para importar o certificado do Cliente UM, selecione a aba "Seus certificados" e clique no botão "Importar". Navegue até o diretório 'ca' dentro da estrutura de diretórios do arquivo de recursos e selecione o arquivo "certificado_cli1.pfx". Serão solicitadas duas senhas:
- a primeira é para acessar o repositório interno utilizado pelo Mozilla: informe a senha pré-existente ou cadastre uma nova;
- a segunda é a senha que foi usada na exportação do certificado: informe "password" ou outra utilizada na exportação (ver seção 6.3).
Os dados do certificado deverão aparecer na lista do gerenciador, como abaixo:
10.4 Acessando uma página não autorizada
Tendo importado o certificado do cliente UM, vamos tentar acessar uma página válida mas não autorizada (por exemplo: https://localhost:9999/utils.h). O resultado deve ser semelhante ao abaixo:
10.5 Acessando páginas autorizadas para o cliente UM
Ao acessar uma página válida e autorizada para o cliente UM (por exemplo: https://localhost:9999/area1/index1.html), o resultado deve ser semelhante ao abaixo:
10.6 Acessando páginas autorizadas para o cliente DOIS
Antes de executar este passo, deve-se importar o certificado do Cliente DOIS no browser, de forma similar ao que foi feito na seção 10.3, atentando para que seja importado o arquivo "certificado_cli2.pfx").
Ao acessar uma página válida e autorizada para o Cliente DOIS (por exemplo: https://localhost:9999/area2/index2.html), o resultado deve ser semelhante ao abaixo:
10.7 Importando os certificados no Internet Explorer e acessando o servidor
Acesssar o menu "Ferramentas/Opções da Internet" e, após abertura do dialog selecionar a aba "Conteúdo" e clicar no botão "Certificados". A partir daí os passos são semelhantes aos procedimentos descritos para o Mozilla. O resultado dos testes de acesso são idênticos aos acima.
11. Roteiro para teste de acesso utilizando o programa cliente
Antes de executar o programa cliente é preciso rodar o script "gera_arquivos_cliente.sh", localizado na raiz do diretório do arquivo de recursos. Ele concatena a chave e o certificado do cliente e gera um arquivo único, como esperado pelo programa:
# Junta os certificados com as chaves privadas,
# conforme esperado pelos programas em 'cliente':
cat ca/certificado_ca.pem > cliente/root.pem
cat ca/certificado_cli1.pem ca/chave_privada_cli1.pem > cliente/client.pem
cat ca/certificado_sv.pem ca/chave_privada_sv.pem > cliente/server.pem
Feito isso, vá para o diretório 'cliente' e digite o comando abaixo, para tentar acessar uma página válida mas sem acesso permitido:
./wclient -h localhost -p 9999 -f utils.h
O resultado é a página HTML abaixo, a qual informa que o usuário (cliente UM) foi identificado, que o recurso não é acessível, e um link para o menu de opções::
HTTP/1.0 200 OKEm seguida, tente o comando abaixo, para tentar acessar uma página válida e com acesso permitido:
<html><body><h2>Desculpe sr(a) usuario(a) clienteUM,</h2><br></body></html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body style="background-color: rgb(255, 255, 204); color: rgb(0, 0, 0);"
link="#0000ee" alink="#0000ee" vlink="#551a8b">
<h3>O recurso solicitado não está disponível para
o seu perfil de usuário.</h3>
<span style="font-weight: bold;"><br>
Estas são as opções de serviço
disponíveis para seu perfil: </span><a
href="https://localhost:9999/area1/index1.html"
style="font-weight: bold;">index1</a><span style="font-weight: bold;">.</span>
br>
<br>
<br>
OBS - O certificado apresentado em sua autenticação
possui Extended Key Usage = OID_CLI_TYPE1<br>
<br>
<span style="font-style: italic;"> <br>
<br style="font-style: italic;">
</span><br>
</body>
</html>
./wclient -h localhost -p 9999 -f area1/index1.html
A resposta deve ser a página solicitada, tal como abaixo:
HTTP/1.0 200 OK
<html><body><h2>Bemvindo sr(a) usuario(a) clienteUM,</h2><br></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<title>index1</title>
</head>
<body style="color: rgb(0, 0, 0); background-color: rgb(153, 255, 255);"
link="#0000ee" alink="#0000ee" vlink="#551a8b">
<span style="font-style: italic;"></span>
<h2>Estas são as opções de serviço
disponíveis para seu perfil de usuário:<br>
</h2>
<br>
<a href="servico_1.1.html"
style="color: rgb(255, 102, 0); font-weight: bold;">Serviço 1.1</a><br>
<br>
<br style="color: rgb(255, 102, 0);">
<a href="servico_1.2.html"
style="color: rgb(255, 102, 0); font-weight: bold;">Serviço 1.2</a><br>
<br>
<br>
<br>
OBS - O certificado apresentado em sua autenticação
possui Extended Key Usage = OID_CLI_TYPE1<br>
<br>
<span style="font-style: italic;"> <br>
<br style="font-style: italic;">
</span><br>
</body>
</html>
12. Considerações Finais
Os programas aqui utilizados são funcionais, mas sua finalidade é didática sendo, por isso, bastante simplificados. Para uma implementação real, num ambiente de produção, muitas melhorias devem ser consideradas, dentre as quais:
Também convém lembrar que está em andamento a especificação de um "Certificados de Atributos" para conter informações sobre autorizações de usuários. Este tipo de certificado será sempre utilizado em conjunto com um certificado X509 padrão, que continua tendo a função de identificar (autenticar) o usuário.
- utilização de mecanismo de sessão para acelerar o handshake SSL a cada solicitação do cliente;
- prover as funcionalidades de sigilo (criptografia) e controle de acesso de forma independentes (por exemplo: efetuar controle de acesso numa requisição sem criptografia);
- utilização de tecnologia de geração de páginas dinâmicas adequada (asp, jsp, php, etc);
- obtenção de OIDs válidos para uso nas extensões dos certificados.
Quanto ao uso de um programa cliente em lugar de um browser, é importante observar que isto pode ser necessário em algumas situações, tais como:
- autenticação/controle de acesso em aplicações cliente "NÃO-WEB";
- aplicação que é servidora num certo contexto é cliente da aplicação que fornece os recursos controlados.
Apêndice A
Arquivo contendo os programas servidor e cliente, scripts e acessórios: recursos.zip