"obsd, cgi" <obsd...@postafiok.hu> wrote:

> So I know the rule.. only remember a few very very long passwords (ex.:
> based on several words and a few special chars), and keep the rest of the
> passwords in a password manager (those aren't remembered and extreme long).
> 
> But this gets me to 2 questions:
> 
> - Are there any default password managers in OpenBSD (console/GUI based?)?
> Or there are only from ports that are not very audited? What is the advise
> to where to store the pwd's?
> 
> - Are there any best-practises to generate a password? - that are kept in
> password manager, so ex.: 128 char long with special/random chars, etc.
> 
> Thanks for your time

I've personally been using a small utility I wrote to generate them from
a plain text database and typed master password. Its passwords aren't as
long as they could be and loss of the master password is catastrophic
since it is used directly and cannot be changed.

- Martin

---

Public domain, but use at your own risk.

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>

static char base64[64] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                          'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                          'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                          'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
                          'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                          'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                          'w', 'x', 't', 'z', '0', '1', '2', '3',
                          '4', '5', '6', '7', '8', '9', '$', '@'};

int main(void)
{
        FILE *tty;
        struct termios originalt, t;
        char buf[100];
        char buf2[100];
        char *s;
        char *mpass;
        EVP_MD_CTX ctx;
        unsigned char key[EVP_MAX_MD_SIZE];
        unsigned int key_len;
        char *site, *account, *date;
        int malformed, hash_error;
        int size;
        unsigned char digest[EVP_MAX_MD_SIZE];
        unsigned int digest_len;
        int i;

        /* Read the master password. */
        tty = fopen("/dev/tty", "r+");
        if (tty == NULL) {
                fprintf(stderr, "Could not read key.");
                return -1;
        }
        fprintf(tty, "Master password: ");
        fflush(tty);
        tcgetattr(fileno(tty), &originalt);
        memcpy(&t, &originalt, sizeof(struct termios));
        t.c_lflag = t.c_lflag & (~ECHO);
        tcsetattr(fileno(tty), TCSANOW, &t);
        if (fgets(buf, 100, tty) == NULL) {
                if (ferror(tty)) {
                        fprintf(stderr, "Could not read key: %s.",
                                strerror(ferror(tty)));
                }
                fprintf(stderr, "Could not read key.");
                return -1;
        }
        tcsetattr(fileno(tty), TCSANOW, &originalt);
        putc('\n', tty);
        fclose(tty);
        s = buf;
        mpass = strsep(&s, "\n");

        /* Generate the SHA512 of the master password. This is the HMAC
           key. */
        EVP_MD_CTX_init(&ctx);
        EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL);
        EVP_DigestUpdate(&ctx, mpass, strlen(mpass));
        key_len = 64;
        EVP_DigestFinal_ex(&ctx, key, &key_len);
        EVP_MD_CTX_cleanup(&ctx);

        /* Read password parameters and calculate password. */
        malformed = hash_error = 0;
        while (fgets(buf, 100, stdin) != NULL) {
                /* Split the input string. */
                s = buf;
                site = strsep(&s, " ");
                if (s == NULL) {
                        malformed = 1;
                        break;
                }
                s = s + strspn(s, " ");
                account = strsep(&s, " ");
                if (s == NULL) {
                        malformed = 1;
                        break;
                }
                s = s + strspn(s, " ");
                date = strsep(&s, " \n");
                if (site == NULL || account == NULL || date == NULL) {
                        malformed = 1;
                        break;
                }
                printf("%s %s %s ", site, account, date);
                /* Perform HMAC-SHA512 on account+site+date. */
                size = snprintf(buf2, 100, "%s%s%s", account, site, date);
                digest_len = 64;
                if (HMAC(EVP_sha512(), key, key_len, buf2, size, digest,
                         &digest_len) == NULL) {
                        hash_error = 1;
                        break;
                }
                /* Calculate the password.
                   Modified base 64 is the same as base 64 except + is
                   $ and / is @ */
                for (i = 0; i < 12; i+=3) {
                        putchar(base64[digest[i]>>2&0x3f]);
                        putchar(base64[(digest[i]&0x3)<<4 | 
digest[i+1]>>4&0xf]);
                        putchar(base64[(digest[i+1]&0xf)<<2 | 
digest[i+2]>>6&0x3]);
                        putchar(base64[digest[i+2]&0x3f]);
                }
                putchar('\n');
        }

        /* I/O error? */
        if (ferror(stdin)) {
                fprintf(stderr, "Error reading stdin: %s.",
                        strerror(ferror(stdin)));
                return -1;
        /* Malformed input? */
        } else if (malformed) {
                fprintf(stderr, "Malformed input.\n");
                return -1;
        /* HMAC error input? */
        } else if (hash_error) {
                fprintf(stderr, "Error performing HMAC-SHA512.\n");
                return -1;
        }
        /* Good! */
        return 0;
}

Reply via email to