Esempio n. 1
0
int initdynstr(dynstr *sout, int isize)
{
	memset(sout,0,sizeof(*sout));
	getstr_dynstr(sout).s=pkg_malloc(isize);
	if (!getstr_dynstr(sout).s) {
		LOG(L_WARN,
			"AUTH_IDENTITY:initdynstr: Not enough memory error\n");
		return -1;
	}
	sout->size=isize;

	return 0;
}
Esempio n. 2
0
/* Checks the Date header of the message. RFC4474 [5] Step 3 */
static int date_proc(struct sip_msg* msg, char* srt1, char* str2)
{
    str sdate;
    int iRes;
    time_t tmsg, tnow;

    if (glb_authservice_disabled) {
        LOG(L_WARN, "AUTH_IDENTITY:date_proc: Authentication Service is disabled\n");
        return -1;
    }

    getstr_dynstr(&glb_sdate).len=0;

    /* we'd like to get the DATE header of the massage */
    iRes=datehdr_proc(&sdate, NULL, msg);
    switch (iRes) {
    case AUTH_ERROR:
        return -1;
    case AUTH_NOTFOUND:
        if (append_date(&getstr_dynstr(&glb_sdate), glb_sdate.size, &tmsg, msg))
            return -2;
        break;
    /* Message has Date header so we check that */
    case AUTH_OK:
#ifdef HAVE_TIMEGM
        tmsg=timegm(&get_date(msg)->date);
#else
        tmsg=_timegm(&get_date(msg)->date);
#endif
        if (tmsg < 0) {
            LOG(L_ERR, "AUTH_IDENTITY:date_proc: timegm error\n");
            return -3;
        }
        if ((tnow=time(NULL))<0) {
            LOG(L_ERR, "AUTH_IDENTITY:date_proc: time error\n");
            return -4;
        }
        /*
         * If the value of this field contains a time different by more than
         * ten minutes from the current time noted by the authentication
         * service then it should reject the message.
         */
        if (tmsg + glb_imsgtime < tnow || tnow + glb_imsgtime < tmsg) {
            LOG(L_INFO, "AUTH_IDENTITY AUTHORIZER: Date header overdue\n");
            return -6;
        }
        break;
    default:
        /* unknown result */
        return -7;
    }

    /*
     * The authentication service MUST verify that the Date header
     * falls within the validity period of its certificate
     * RFC 4474 [6] Step 3
     */
    if (glb_imycertnotafter < tmsg) {
        LOG(L_INFO, "AUTH_IDENTITY AUTHORIZER: My certificate has been expired\n");
        return -8;
    }

    return 1;
}
Esempio n. 3
0
/*
 * Concates the message From, To, Call-ID, Cseq, Date,  Contact header fields
 * and the message body to digest-string, signs with the domain private-key,
 * BASE64 encodes that, and finally adds it to the message as the 'Identity'
 * header value. RFC4474 [5] Step 4
 *
 * Adds Identity-Info header to the message which contains an URI from which
 * its certificate can be acquired. RFC4474 [5] Step 4
 */
static int add_identity(struct sip_msg* msg, char* srt1, char* str2)
{
    int iRes;
    str sstr;


    if (glb_authservice_disabled) {
        LOG(L_WARN, "AUTH_IDENTITY:add_identity: Authentication Service is disabled\n");
        return -1;
    }

    /* check Date */
    iRes=datehdr_proc(NULL, NULL, msg);
    switch (iRes) {
    case AUTH_ERROR:
        return -1;
    case AUTH_NOTFOUND:
        if (!getstr_dynstr(&glb_sdate).len) {
            /*
             * date_proc() must be called before add_identity() because
             * that function initializes the Date if that not exists
             * in the SIP message
             */
            LOG(L_ERR, "AUTH_IDENTITY:add_identity: Date header is not found (has auth_date_proc been called?)\n");
            return -2;
        }
        /*  assemble the digest string and the DATE header is missing in the orignal message */
        if (digeststr_asm(&glb_sdgst,
                          msg,
                          &getstr_dynstr(&glb_sdate),
                          AUTH_OUTGOING_BODY | AUTH_ADD_DATE))
            return -3;
        break;
    default:
        /*  assemble the digest string and the DATE header is available in the message */
        if (digeststr_asm(&glb_sdgst, msg, NULL, AUTH_OUTGOING_BODY))
            return -4;
        break;
    }

    /* calculate the SHA1 hash and encrypt with our provate key */
    if (rsa_sha1_enc(&glb_sdgst, &glb_encedmsg, &glb_b64encedmsg, glb_hmyprivkey))
        return -5;

    /* we assemble the value of the Identity haader */
    sstr.s=IDENTITY_FIRST_PART;
    sstr.len=strlen(IDENTITY_FIRST_PART);
    if (cpy2dynstr(&glb_sidentity, &sstr))
        return -6;

    if (app2dynstr(&glb_sidentity, &getstr_dynstr(&glb_b64encedmsg)))
        return -7;

    sstr.s=IDENTITY_LAST_PART;
    /* +1 : we need the trailing \0 character too */
    sstr.len=strlen(IDENTITY_LAST_PART) + 1;
    if (app2dynstr(&glb_sidentity, &sstr))
        return -8;

    if (append_hf(msg, getstr_dynstr(&glb_sidentity).s, HDR_IDENTITY_T))
        return -9;

    if (append_hf(msg, getstr_dynstr(&glb_sidentityinfo).s, HDR_IDENTITY_INFO_T))
        return -10;

    return 1;
}
Esempio n. 4
0
/*
 * If the digest-string, assembled from the message, corresponds to the string
 * decoded from the Identity header by the acquired public key then the message
 * is valid. RFC 4474 [6] Step 3
 */
static int check_validity(struct sip_msg* msg, char* srt1, char* str2)
{
    str sidentity;
    char sencedsha[HASH_STR_SIZE];
    int iencedshalen;
#ifndef NEW_RSA_PROC
    char ssha[HASH_STR_SIZE];
#endif
    int ishalen;
    unsigned char sstrcrypted[SHA_DIGEST_LENGTH];
    int iRet=1;


    if (!glb_pcertx509) {
        LOG(L_ERR, "AUTH_IDENTITY:check_validity: Certificate uninitialized! (has vrfy_get_certificate been called?)\n");
        return -1;
    }

    do {
        /* get the value of identity header parsed */
        if (identityhdr_proc(&sidentity, NULL, msg)) {
            iRet=-1;
            break;
        }

        /* the length of identity value should be 172 octets long */
        if (sidentity.len > sizeof(sencedsha)) {
            LOG(L_ERR, "AUTH_IDENTITY:check_validity: Unexpected Identity length (%d)\n", sidentity.len);
            iRet=-2;
            break;
        }

        /* base64 decode the value of Identity header */
        base64decode(sidentity.s, sidentity.len, sencedsha, &iencedshalen);

        /* assemble the digest string to be able to compare it with decrypted one */
        if (digeststr_asm(&glb_sdgst, msg, NULL, AUTH_INCOMING_BODY)) {
            iRet=-5;
            break;
        }
        /* calculate hash */
        SHA1((unsigned char*)getstr_dynstr(&glb_sdgst).s,
             getstr_dynstr(&glb_sdgst).len,
             sstrcrypted);

#ifdef NEW_RSA_PROC
        /* decrypt with public key retrieved from the downloaded certificate
           and compare it with the calculated digest hash */
        if (rsa_sha1_dec(sencedsha, iencedshalen,
                         (char *)sstrcrypted, sizeof(sstrcrypted), &ishalen,
                         glb_pcertx509)) {
            iRet=-3;
            break;
        } else
            LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Identity OK\n");
#else
        /* decrypt with public key retrieved from the downloaded certificate */
        if (rsa_sha1_dec(sencedsha, iencedshalen,
                         ssha, sizeof(ssha), &ishalen,
                         glb_pcertx509)) {
            iRet=-3;
            break;
        }

        /* check size */
        if (ishalen != sizeof(sstrcrypted)) {
            LOG(L_ERR, "AUTH_IDENTITY:check_validity: Unexpected decrypted hash length (%d != %d)\n", ishalen, SHA_DIGEST_LENGTH);
            iRet=-4;
            break;
        }
        /* compare */
        if (memcmp(sstrcrypted, ssha, ishalen)) {
            LOG(L_INFO, "AUTH_IDENTITY VERIFIER: comparing hashes failed -> Invalid Identity Header\n");
            iRet=-6;
            break;
        } else
            LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Identity OK\n");
#endif
    } while (0);

    glb_pcertx509=NULL;

    return iRet;
}