WA-SDK  3.0.4.0
WA-SDK
issacapi/easig/sample_easig_basic.c
#include <stdio.h>
#include "issacapi_bs.h"
#include "issacapi_usr.h"
static const char *certB64 =
"MIIFszCCBJugAwIBAgICAZkwDQYJKoZIhvcNAQELBQAwSzELMAkGA1UEBhMCS1IxEDAOBgNVBAoMB0lOSVBBU1MxFTATBgNVBAsMDEFjY3JlZGl0"
"ZWRDQTETMBEGA1UEAwwKSU5JUEFTUyBDQTAeFw0xOTAzMTEwNTA0NTlaFw0xOTA2MDkxNDU5NTlaMIGCMQswCQYDVQQGEwJLUjEQMA4GA1UECgwH"
"SU5JUEFTUzERMA8GA1UECwwIcGVyc29uYWwxFDASBgNVBAsMC0lOSVBBU1MyMDAwMTgwNgYDVQQDDC/snbTri4jthY3qsJzsnbgoSW5pUGVyKTIw"
"MDA4MDEyMDE5MDMxMTkwMDAwMDAwMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIrdG5fdGmTME6FpzwbFb5HBRojBKfbsSrpyiHlq"
"n1uKBaaajoBsYIeNbOwg7roLkQvm0uodET4G3MWRJaAGGOtbIKffFd7nPo1oELinQvF2Gcr2siwgSI7YbvAnPI5s11Dc4D86NqS/b+tC/zSNuLUX"
"bBKVoxUHG4E7IEEcK1zF5LLalvPFFwVhLx/IsylCvkHWw900jKGeBgBsFDklRDdSFI/jwiMnJgMtGYFxakXh6pMgzof4DQNCsA/8beHQ37iBXKoA"
"380/tB3TFDJA2AB0KuOQDeFbvRLaiyqx7UNcWM6AM7ubcrj4B2XoS6zPTo85Dx6iQTaLPkwEQ6ilXDECAwEAAaOCAmcwggJjMIGPBgNVHSMEgYcw"
"gYSAFKORisOXVoYiGgulHJtUsiz4oqcFoWikZjBkMQswCQYDVQQGEwJLUjENMAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNh"
"dGlvbiBBdXRob3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgNIICECQwHQYDVR0OBBYEFFIslyxQUQ9/Bdlkw+0AiXaD150XMA4G"
"A1UdDwEB/wQEAwIGwDB8BgNVHSABAf8EcjBwMG4GCiqDGoyaRAUFAQEwYDAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5pbmlwYXNzLmNvbS9tYS9Q"
"T18wNC5hZzAuBggrBgEFBQcCAjAiHiDHdAAgx3jJncEcspQAIKz1x3jHeMmdwRwAIMeFssiy5DBuBgNVHREEZzBloGMGCSqDGoyaRAoBAaBWMFQM"
"D+ydtOuLiO2FjeqwnOyduDBBMD8GCiqDGoyaRAoBAQEwMTALBglghkgBZQMEAgGgIgQgeIkP8+qhOB5hQLxSg2CoENfDcrxKlJG9Fskt3RRSt4ow"
"dwYDVR0fBHAwbjBsoGqgaIZmbGRhcDovL2Rpci5pbmlwYXNzLmNvbTozODkvb3U9ZHA4MXAxLG91PWNybGRwLG91PUFjY3JlZGl0ZWRDQSxvPUlO"
"SVBBU1MsYz1rcj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0MDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcwAYYdaHR0cDovL29jc3AuaW5pcGFz"
"cy5jb206NDYxMi8wDQYJKoZIhvcNAQELBQADggEBADouu5wh+r1t0+elJZAScMwIBUNRcG/41aV6M9mjXVHTPj+874IeOqghlvVPdiRPGQl6RdXy"
"E+QtVa2VM2yTgQjB0WP8iVRJmcHGj5oH2X1HV6Og0FhmgL+BNflrEzTuvu3FnYUgCynDGCNTl26beP2CVXUVcPiGasKSwxIoya8RtybzTQD1gZLv"
"ZDEXqAGeYFKPNU+V4mTolDaB7+P+W98cGD47ai4efy0e4id8x6cl9eAMA7rCkshylxZnuPk6lOflR1SsRgAyzcT288yRuViEc/rKGGhrYz9fJGuS"
"5Sz0PUTKzkxxn3/BPOhvRdgKSRBMX4ZGFqgiynj6qbZBqnQ=";
static unsigned char certBytes[4096] = { 0, };
static int certBytesLen = 0;
static const char *priKeyB64 =
"MIIFEDAaBggqgxqMmkQBDzAOBAg0ThZK2Xze5gICCAAEggTw5gK4W3R5WZIHGfvDlATewr8N18VcvqPpO8ruIXHSQBeJpUvTiVZMU+2AJfkTGzXZ"
"xLfd+oUF+uzBPm2MV5xPVQsDr6ktFsTrqSUe+gunx9M9XH9UHPPj6xqwdsv0JJLTAQx/vi+Cd3AP0rYmxMvamUfXk7UQvsGI32Wj0P1WJ1bkgRNm"
"IO+uMGKH/bp78W20L4CyhhxrlaAeZT0uVE6HvVxONHKxbmq8BDKKrWp5QIcihQhXgvjxtH7UjwQaOqZZOBZn4eN6aZZahn20jCJqoSGYUSGzGHaT"
"HcOTnQqxLJIo0n043nUKPglVU58uNPUjEy17hhoWs/r4unfVmQqpaIChJjQNKy82MptXvtyPCtyf/bvHBA8PL7oDfZy+UNtQIXGZW+jFMTr5DMQ2"
"6LwzyHg8BD5dlSl5Yw6UtpwrmL06fso7vBbZc7gV2QRFaFCH734/UJ3ig41/yEPGUvEwlB9y3xNeTaNQPA+9AZfnSaRHX93Z5iOf2VU7Q9YcIRp4"
"RRC6K6kENNNGszAaFlSqNMN5rWuF0/9xX7gYF7sqqdlAAClAZMM/JUdD5SOS412AyKJHuIpC4pngF65AebihkjjJxL86+h1qZ2wGq2e07hY16l2r"
"YsU8zpUrJNBYaH01xIRm9+zJHXUbLxD9moNGAAQcSfE1EDhykTmWL9FNtf+94xsDfLAdIB9OXt9hQBBYHm44iWxmqz35C23SPBba6zZAobjFt9mv"
"nPpFLJ6nGRdojKvxUhk+zd4UPYpMXvdHx9m4XlPTUcdSzjXx7cjsxeRaAYSUPm/M1fBOhnisRII13r/z5HhKM3jt11XW1670DKv2+lPinE28iOOE"
"qpVH5ja4rRb8JCYLaWu6QchM+5g3ALBUC5K10RJ80RthgHsDOeQS7tSJPALZGQYB8X92LGm+AypvC6DIIJMBWv0QxTPpY7aLoNZ1OIjzRiQX/vaz"
"IhCo8uPGMbhictVxSXxD1pMnkApDcdU628xoTeZwcfzx2j2MaDQPwefmxKANhJqx+rLtLyNqocjUm5FadwNKfp8Yrk+gMQ3v1KvO+LuFtq8BcQXw"
"EkbrYv2byX793kqvdDa4Q7DgMc4c47UtiDVmBEmfNWFiSj0Y8K6VFcxCLg5NnD84L91/kDrTMK2vp3Oqm9yaVCz6I7ljhjfxfwf/DfUjvgmajYjH"
"WZ40dGL+NxLPWwajwTZ3Ed7StNzj/sKFL1lH3fDH/99i4duVIrfQntVqZATpo3pQ6EaWj/HBInFpsXthcXGC3kMZt2aPDn8hKp13ypb8Tp4EYd9w"
"v7uTgbK/InjgvjNYq/6NjxqOd1YFK1u0+w0r0cIMKeoGMhbBpsRKNamhDfBlekewk5mBioQzlOZRStZakUDdhzj3YtQdPSrR4TYqnVIFp7ylh+Jz"
"D11Sj5NmgmMWwYhwuw2ceh2Rg+qU/C2pDw1loRd+G6XE6Pv2+YOnCGk+ne8Wg92fSSCNkcHmai3JyWTjT1RQSfWUHGHfaKQUKkm3E0p8JdMCaJt7"
"9wJYIJF5LnCFqUlVEOQbjB0F3eVaw7YpzKd/layjwRT6TvXVFMknFtYaVGKPEZGHf/FXCVOR9IPYY6riPDwhNCHz6/n0h2v2MZ0wdch8q43V/rMP"
"s8OvwMFhUyxevCtxajQsdIF2lM4yAUJrZgFP5OuJ1ycfF1z/vRsl5g==";
static unsigned char priKeyBytes[2048] = { 0, };
static int priKeyBytesLen = 0;
static const char *password = "Inipass@2019";
static int sample_setup() {
ISSAC_RETURN result;
result = ISSAC_Initialize();
if (result != ISSAC_SUCCESS) {
printf("[ERROR] %s\n", ISSAC_GetErrorMessage(result));
return 1;
}
result = ISSAC_BASE64_Decode(certBytes, &certBytesLen, sizeof(certBytes), certB64);
if (result != ISSAC_SUCCESS) {
printf("[ERROR] %s\n", ISSAC_GetErrorMessage(result));
return 1;
}
result = ISSAC_BASE64_Decode(priKeyBytes, &priKeyBytesLen, sizeof(priKeyBytes), priKeyB64);
if (result != ISSAC_SUCCESS) {
printf("[ERROR] %s\n", ISSAC_GetErrorMessage(result));
return 1;
}
return 0;
}
static ISSAC_RETURN sample_make_challenge(unsigned char *challenge, int *challengeLen, int challengeBufLen) {
ISSAC_RETURN result;
EASIGCONTEXT verifierInfo;
ISSAC_EASIGCONTEXT_Create(&verifierInfo);
result = ISSAC_EA_SIG_MakeChallenge(challenge, challengeLen, challengeBufLen, &verifierInfo);
ISSAC_EASIGCONTEXT_Delete(&verifierInfo);
return result;
}
static ISSAC_RETURN sample_make_response(unsigned char *response, int *responseLen, int responseBufLen, const unsigned char *challenge, int challengeLen) {
ISSAC_RETURN result;
PRIVATEKEY priKey;
EASIGCONTEXT proverInfo;
// 인증서 읽기
result = ISSAC_CERTIFICATE_Read_Memory(&cert, certBytes, certBytesLen);
// 개인키 읽기
if (result == ISSAC_SUCCESS) {
result = ISSAC_PRIVATEKEY_Read_Memory(&priKey, priKeyBytes, priKeyBytesLen, password);
}
// 응답값 생성
if (result == ISSAC_SUCCESS) {
result = ISSAC_EA_SIG_MakeResponse(response, responseLen, responseBufLen, challenge, challengeLen, &priKey, &cert, &proverInfo);
}
return result;
}
static ISSAC_RETURN sample_verify_response(const unsigned char *challenge, int challengeLen, const unsigned char *response, int responseLen) {
ISSAC_RETURN result;
EASIGCONTEXT verifierInfo;
ISSAC_EASIGCONTEXT_Create(&verifierInfo);
// 응답값 검증
// - 챌린지값을 생성할 때 사용했던 EASIGCONTEXT 객체를 유지하고 있다면 challenge를 넣어줄 필요는 없고, 아니면 챌린지를 넣어줘야 한다.
// - 객체 유지보다는 챌린지값을 유지하는 방법이 많이 사용될 것 같아서 이 샘플도 챌린지값을 유지하는 방법을 사용한다.
result = ISSAC_EA_SIG_AuthenticatePeerMessage(challenge, challengeLen, response, responseLen, &verifierInfo);
if (result == ISSAC_SUCCESS) {
// 응답값 생성에 사용된 인증서의 유효성 검증
result = ISSAC_EA_SIG_GetPeerCertificate(&cert, &verifierInfo);
// inipass 서비스 종료로 테스트 불가
// if (result == ISSAC_SUCCESS) {
// // ISSAC_USR_CertPathValidation() 은 공인인증서와 같이 LDAP이 사용되는 경우에만 가능함. API 문서 참고.
// result = ISSAC_USR_CertPathValidation(&cert);
// }
}
ISSAC_EASIGCONTEXT_Delete(&verifierInfo);
return result;
}
static int sample_easig_basic() {
ISSAC_RETURN result;
char challenge[64] = { 0, };
int challengeLen = 0;
char response[2048] = { 0, };
int responseLen = 0;
// 개체 인증은 서버와 클라이언트가 상호작용을 해야 한다. 따라서 샘플도 각각에 맞게 분리하였다.
printf("sample_easig_basic() => ");
// 서버(검증자) : 챌린지값을 생성하여 클라이언트(요청자)에게 전달
result = sample_make_challenge(challenge, &challengeLen, sizeof(challenge));
// 클라이언트(요청자) : 서버에게 전달받은 챌린지값을 사용하여 응답값 생성
if (result == ISSAC_SUCCESS) {
result = sample_make_response(response, &responseLen, sizeof(response), challenge, challengeLen);
}
// 서버(검증자) : 클라이언트에게 전달받은 응답값 검증
if (result == ISSAC_SUCCESS) {
result = sample_verify_response(challenge, challengeLen, response, responseLen);
}
//if (result == ISSAC_SUCCESS) {
// 테스트 인증서가 만료된 경우를 대비하여 만료도 성공으로 한다. (실서버 반영시 만료는 만료로 처리해야 함)
if (result == ISSAC_SUCCESS || result == ER_VERIFY_EXPIRED) {
printf("[OK]\n");
return 0;
} else {
printf("[ERROR] %s\n", ISSAC_GetErrorMessage(result));
return 1;
}
}
int main() {
int result;
result = sample_setup();
if (result != 0) {
return result;
}
return sample_easig_basic();
}
@ ER_VERIFY_EXPIRED
(70103)
Definition: issacapi_errorcode.h:112
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_CERTIFICATE_Delete(CERTIFICATE *cert)
CERTIFICATE 에 할당된 메모리를 해제한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_CERTIFICATE_Create(CERTIFICATE *cert)
CERTIFICATE 를 초기화한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_CERTIFICATE_Read_Memory(CERTIFICATE *cert, const void *buffer, int buffer_len)
인증서를 버퍼에서 읽어들인다. (DER, BASE64, PEM)
unsigned int ISSAC_RETURN
ISSAC-API 실행 결과 [ ISSACAPI_BASIC_RETURN, ISSACAPI_ERRORS, ISSAC_LICENSE_ERR ]
Definition: issacapi_bs_definitions.h:32
@ ISSAC_SUCCESS
(0) 성공
Definition: issacapi_bs_definitions.h:37
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_BASE64_Decode(void *data, int *data_len, int data_alloc_len, const char *code)
입력한 BASE64 문자열을 바이너리 데이터로 디코딩한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_Initialize(void)
모듈을 초기화한다.
WA_SDK_API const char *FUNCCALL ISSAC_GetErrorMessage(ISSAC_RETURN errorCode)
ISSAC-API 의 에러코드에 대한 에러메시지를 가져온다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_PRIVATEKEY_Read_Memory(PRIVATEKEY *privatekey, const void *buffer, int buffer_len, const char *pin)
PKCS#8 개인키를 버퍼에서 읽어들인다. (DER)
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_PRIVATEKEY_Create(PRIVATEKEY *key)
PRIVATEKEY 를 초기화한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_PRIVATEKEY_Delete(PRIVATEKEY *key)
PRIVATEKEY 에 할당된 메모리를 해제한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EA_SIG_GetPeerCertificate(CERTIFICATE *cert, EASIGCONTEXT *verifierInfo)
Response에서 개체인증 대상자의 인증서를 추출한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EA_SIG_MakeResponse(void *response, int *response_size, int response_buffer_size, const void *challenge, int challenge_size, PRIVATEKEY *priKey, CERTIFICATE *cert, EASIGCONTEXT *proverInfo)
개체인증 요청자가 생성한 Challenge를 이용하여 Response를 생성한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EASIGCONTEXT_Create(EASIGCONTEXT *easiginfo)
EASIGCONTEXT 구조체를 초기화한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EA_SIG_AuthenticatePeerMessage(const void *challenge, int challenge_size, const void *response, int response_size, EASIGCONTEXT *verifierInfo)
개체인증 대상자의 Response를 검증하여 해당 개체를 인증한다. (인증서 검증은 하지 않음)
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EA_SIG_MakeChallenge(void *challenge, int *challenge_size, int challenge_buffer_size, EASIGCONTEXT *verifierInfo)
개체인증 요청자가 개체인증을 위한 Challenge를 생성한다.
WA_SDK_API ISSAC_RETURN FUNCCALL ISSAC_EASIGCONTEXT_Delete(EASIGCONTEXT *easiginfo)
EASIGCONTEXT 에 할당된 메모리를 해제한다.
인증서에 대한 컨텍스트
Definition: issacapi_bs_definitions.h:106
개체인증 컨텍스트
Definition: issacapi_ea_sig.h:27
PKCS#8 형식의 개인키에 대한 컨텍스트
Definition: issacapi_bs_definitions.h:152