⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 roil.c

📁 使用OpenSSL协议对网络传输文件加密并解密。是编写网络安全工具的首选。
💻 C
📖 第 1 页 / 共 2 页
字号:
}introil_cipher(struct roil_pack *rp){    int n, m, mode;    EVP_CIPHER_CTX ea_context;    const EVP_CIPHER *ea;    u_long bytecnt;    u_char buf[BUF_SIZE], ebuf[BUF_SIZE], key[KEY_LENGTH], iv[IV_LENGTH];    /* set the mode for the cipher functions */    mode = (rp->flags & ENCRYPT) ? 1 : 0;    /* add all available encryption algorithms to the hash table */    OpenSSL_add_all_ciphers();    if (rp->flags & ENCRYPT)    {        /*         *  If we're encrypting, we have to first load and verify the          *  cipher specified at the command line.         */        ea = EVP_get_cipherbyname(rp->ea);        if (ea == NULL)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "unknown cipher %s\n",                    rp->ea);            return (-1);        }    }    else    /* decrypting */    {        /*         *  If we're decrypting, we have to check to see if this file was          *  previously encrypted by roil.  To do that, we read the first 8          *  bytes and see if they correspond to the "magic number" that is         *  written to every roiled file prior to encryption.         */        n = read(rp->fd_in, buf, 8);        if (n != 8)        {               snprintf(rp->errbuf, ERRBUF_SIZE, "read error %s\n",                    strerror(errno));            return (-1);        }        if (bcmp(buf, magic, 8))        {               snprintf(rp->errbuf, ERRBUF_SIZE, "%s is not a roiled file\n",                    rp->fn_in);            return (-1);        }        /*         *  Next, we have to determine which symmetric cipher was used         *  to encrypt the file.  That is written in the next 16 bytes         *  of the file.         */        n = read(rp->fd_in, buf, 16);        if (n != 16)        {               snprintf(rp->errbuf, ERRBUF_SIZE, "read error %s\n",                    strerror(errno));            return (-1);        }        /*         *  Look up the cipher by canonical name and if it's "good" fill         *  in an EVP_CIPHER structure.         */        ea = EVP_get_cipherbyname(buf);        if (ea == NULL)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "unknown cipher %s\n",                    buf);            return (-1);        }        /*         *  The next 8 bytes contain the initialization vector, which         *  may or may not be used by the algorithm.  We store it either         *  way.         */        n = read(rp->fd_in, iv, 8);        if (n != 8)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "read error %s\n",                    strerror(errno));            return (-1);        }    }    /*     *  Get a passphrase from the user to use as a key for the symmetric      *  encryption.     */    if (get_passphrase(rp->passphrase) == -1)    {        snprintf(rp->errbuf, ERRBUF_SIZE, "can't read passphrase %s\n",                strerror(errno));        return (-1);    }    /*     *  Take the passphrase and hash it using SHA1 to create our     *  symmetric key.     */    if (make_key(rp, key)  == -1)    {        /* error set in roil_digest() */        return (-1);    }    /* we appear good to go; we open our output file */    if (open_outputfile(rp) == -1)    {        /* error set in open_outputfile() */        return (-1);    }    if (rp->flags & ENCRYPT)    {        /*         *  Write out our 8 byte magic number to the file.  This will         *  let the decryption code know if this file was encrypted by         *  us or not.         */        n = write(rp->fd_out, magic, 8);        if (n != 8)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "write error %s\n",                    strerror(errno));            return (-1);        }        /*         *  Write the encryption algorithm to the file, which will be         *  NULL padded to 16 bytes.  This will allow the decryption         *  code to figure it out without needing the user to specify.         */        memset(buf, 0, sizeof (buf));        memcpy(buf,  rp->ea, strlen(rp->ea));        n = write(rp->fd_out, buf, 16);        if (n != 16)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "write error %s\n",                    strerror(errno));            return (-1);        }        /*         *  Some encryption algorithms use an initialization vector to         *  seed the first round of encryption with (it acts as a dummy         *  block).  We might need it so we'll get one and write it to         *  the file next.         */        get_iv(iv);        n = write(rp->fd_out, iv, 8);        if (n != 8)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "write error %s\n",                    strerror(errno));            return (-1);        }    }    /*     *  Initialize the cipher context.  Really all this does is zero     *  out the structure.     */    EVP_CIPHER_CTX_init(&ea_context);    /* initialize the encryption/decryption operation */    if (EVP_CipherInit_ex(&ea_context, ea, NULL, key, iv, mode) == 0)    {        snprintf(rp->errbuf, ERRBUF_SIZE, "EVP_CipherInit_ex() failed\n");        return (-1);    }    /*     *  Encrypt/decrypt the file.  Read a block of data, encrypt it and      *  write it out to the file.     */    if (rp->flags & ENCRYPT)    {        fprintf(stderr, "\nencrypting file \"%s\"\n", rp->fn_in);    }    else    {        fprintf(stderr, "\ndecrypting %s encrypted file \"%s\"\n", buf,                rp->fn_in);    }    bytecnt = 0;    while ((n = read(rp->fd_in, buf, sizeof (buf))) > 0)    {        bytecnt += n;        /*         *  Encrypt or decrypt n bytes from buf and write the output to         *  ebuf.         */        if (EVP_CipherUpdate(&ea_context, ebuf, &m, buf, n) == 0)        {            snprintf(rp->errbuf, ERRBUF_SIZE,                    "EVP_CipherUpdate() failed\n");            return (-1);        }        n = write(rp->fd_out, ebuf, m);        if (n != m)        {            snprintf(rp->errbuf, ERRBUF_SIZE, "write error %s\n",                    strerror(errno));            return (-1);        }        fprintf(stderr, "byte: 0x%08lx\r", bytecnt);    }    /*     *  Finalize the encryption or decryption by taking care of padding      *  the last block if necessary.     */    if (EVP_CipherFinal_ex(&ea_context, ebuf, &m) == 0)    {        snprintf(rp->errbuf, ERRBUF_SIZE,                "EVP_CipherFinal_ex() failed\n");        return (-1);    }    n = write(rp->fd_out, ebuf, m);    if (n != m)    {        snprintf(rp->errbuf, ERRBUF_SIZE, "write error %s\n",                strerror(errno));        return (-1);    }    printf("\ndone, output file is \"%s\"\n", rp->fn_out);    return (1);}intget_passphrase(char *passphrase){    int n, retry;    char passphrase_match[KEY_LENGTH];    struct termios term;    /* we want to turn off terminal echoing so no one can see! */    n = tcgetattr(STDIN_FILENO, &term);    if (n == -1)    {        fprintf(stderr, "warning: password will be echoed\n");        /* nonfatal */    }    else    {        /* disable terminal echo */        term.c_lflag &= ~ECHO;    }    /* set our changed state "NOW" */    n = tcsetattr(STDIN_FILENO, TCSANOW, &term);    if (n == -1)    {        fprintf(stderr, "warning: password will be echoed\n");        /* nonfatal */    }    retry = RETRY_THRESHOLD;    memset(passphrase, 0, KEY_LENGTH);again:    printf("Passphrase: ");    if (fgets(passphrase, KEY_LENGTH, stdin) == NULL)    {        return (-1);    }    passphrase[strlen(passphrase) - 1] = 0;    printf("\nAgain: ");    if (fgets(passphrase_match, KEY_LENGTH, stdin) == NULL)    {        return (-1);    }    passphrase_match[strlen(passphrase_match) - 1] = 0;    /*     *  Check to make sure they match.  It's safe to use strcmp here     *  since we're confident both strings will be KEY_LENGTH or fewer      *  bytes.     */    if (strcmp(passphrase, passphrase_match))    {        if (retry <= 0)        {            /* we've run through this RETRY_THRESHOLD times, we're done */            fprintf(stderr, "\nyou're hopeless; get typing lessons\n");            errno = EPERM;  /* this is as good as any I suppose */            return (-1);        }        fprintf(stderr, "\nno doofus, they don't match, try again\n");        retry--;        goto again;    }    memset(passphrase_match, 0, KEY_LENGTH);    return (1);}intmake_key(struct roil_pack *rp, u_char *key){    int len;    u_char *p;    strncpy(rp->md, "sha1", 4);    p = roil_digest(rp, &len);    if (p == NULL)    {        /* error set in roil_digest() */        return (-1);    }    memcpy(key, p, len);    return (1);}voidget_iv(u_char *iv){    int n;    /* XXX - should use the rand() interface from OpenSSL */    srandom((unsigned)time(NULL));    /* get 8 bytes of pseudo random value, from 0 - 255 */    for (n = 0; n < IV_LENGTH; n++)    {        iv[n] = random() % 0xff;    }}voidusage(char *name){    printf("usage %s [options] file\n"                    "-e cipher_type\t\tencrypt\n"                    "-d\t\t\tdecrypt\n"                    "-h\t\t\tthis blurb you see right here\n"                    "-m message_digest\tmessage digest\n", name);}/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -