Esempio n. 1
0
File: ipc.c Progetto: hno/fribid
static BankIDError waitReply(PipeInfo *pipeinfo) {
    pipe_finishCommand(pipeinfo->out);
    
    pipe_waitData(pipeinfo->in);
    
    // Return error code
    return pipe_readInt(pipeinfo->in);
}
Esempio n. 2
0
File: pipe.c Progetto: hno/fribid
void pipe_readData(FILE *in, char **data, int *length) {
    *length = pipe_readInt(in);
    if (*length <= 0) {
        *length = 0;
        *data = NULL;
        return;
    }
    
    *data = malloc(*length);
    if ((*data == NULL) || (fread(*data, *length, 1, in) != 1)) {
        pipeError();
        free(*data);
        *length = 0;
    }
}
Esempio n. 3
0
File: pipe.c Progetto: hno/fribid
char *pipe_readString(FILE *in) {
    int length = pipe_readInt(in);
    if (length <= 0) return strdup("");
    
    char *data = malloc(length +1);
    if (!data) {
        pipeError();
        return strdup("");
    }
    
    data[length] = '\0';
    if (fread(data, length, 1, in) == 1) {
        return data;
    } else {
        pipeError();
        free(data);
        return strdup("");
    }
}
Esempio n. 4
0
File: main.c Progetto: fyra/fribid
/**
 * Called when a command is being sent from the plugin.
 */
void pipeCommand(PipeCommand command, const char *url, const char *hostname,
                 const char *ip) {
    switch (command) {
        case PC_GetVersion: {
            char *versionString = bankid_getVersion();
            
            pipe_sendString(stdout, versionString);
            free(versionString);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        case PC_Authenticate:
        case PC_Sign: {
            char *challenge = pipe_readString(stdin);
            int32_t serverTime = pipe_readInt(stdin);
            free(pipe_readOptionalString(stdin)); // Just ignore the policies list for now
            char *subjectFilter = pipe_readOptionalString(stdin);
            char *messageEncoding = NULL, *message = NULL,
                 *invisibleMessage = NULL;
            if (command == PC_Sign) {
                messageEncoding = pipe_readString(stdin);
                message = pipe_readString(stdin);
                invisibleMessage = pipe_readOptionalString(stdin);
            }
            
            // Validate input
            BankIDError error = BIDERR_OK;
            
            if (!is_https_url(url)) {
                error = BIDERR_NotSSL;
            } else if (!is_canonical_base64(challenge) ||
                       !is_valid_hostname(hostname) ||
                       !is_valid_ip_address(ip) ||
                       (command == PC_Sign && (
                           !is_canonical_base64(message) ||
                           (invisibleMessage && !is_canonical_base64(invisibleMessage))
                       ))) {
                error = BIDERR_InternalError;
            }
            
            if (error != BIDERR_OK) {
                pipe_sendInt(stdout, error);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }
            
            if (subjectFilter && !is_canonical_base64(subjectFilter)) {
                // The subject filter is invalid. Ignore it
                free(subjectFilter);
                subjectFilter = NULL;
            }
            
            Token *token;
            char *password = NULL;
            long password_maxsize = 0;
            char *signature = NULL;
            char *decodedSubjectFilter = NULL;
            error = BIDERR_UserCancel;

            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) {
                pipe_sendInt(stdout, BIDERR_InternalError);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }

            if (subjectFilter) {
                decodedSubjectFilter = base64_decode(subjectFilter);
                free(subjectFilter);
            }
            
            // Pass all parameters to the user interface
            platform_startSign(url, hostname, ip, browserWindowId);
            BackendNotifier *notifier = backend_createNotifier(
                decodedSubjectFilter,
                (command == PC_Sign ?
                    KeyUsage_Signing : KeyUsage_Authentication),
                notifyCallback);
            platform_setNotifier(notifier);
            platform_addKeyDirectories();
            backend_scanTokens(notifier);
            free(decodedSubjectFilter);
            
            if (command == PC_Sign) {
                if (!message) abort();
                char *decodedMessage = base64_decode(message);
                platform_setMessage(decodedMessage);
                free(decodedMessage);
            }

            while (platform_sign(&token, password, password_maxsize)) {
                // Set the password (not used by all backends)
                token_usePassword(token, password);
                
                // Try to authenticate/sign
                if (command == PC_Authenticate) {
                    error = bankid_authenticate(token, challenge, serverTime,
                                                hostname, ip, &signature);
                } else {
                    error = bankid_sign(token, challenge, serverTime,
                                        hostname, ip, messageEncoding,
                                        message, invisibleMessage,
                                        &signature);
                }
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                // An error occurred
                const TokenError tokenError = token_getLastError(token);
                platform_showError(tokenError);
                if (tokenError == TokenError_BadPassword || tokenError == TokenError_BadPin) {
                    platform_focusPassword(); // also removes focus from the Sign button
                }
                error = BIDERR_UserCancel;
            }

            secmem_free_page(password);

            platform_endSign();
            
            backend_freeNotifier(notifier);
            free(messageEncoding);
            free(message);
            free(invisibleMessage);
            free(challenge);
            
            pipe_sendInt(stdout, error);
            pipe_sendString(stdout, (signature ? signature : ""));
            pipe_flush(stdout);
            
            free(signature);
            platform_leaveMainloop();
            break;
        }
        case PC_CreateRequest: {
            char *request = NULL;
            BankIDError error = BIDERR_InternalError;
            long password_maxsize = 0;
            char *name = NULL;
            char *password = NULL;
            
            // Read input
            RegutilInfo input;
            memset(&input, 0, sizeof(input));
            
            input.minPasswordLength = pipe_readInt(stdin);
            input.minPasswordNonDigits = pipe_readInt(stdin);
            input.minPasswordDigits = pipe_readInt(stdin);
            
            while (pipe_readInt(stdin) == PLS_MoreData) {
                // PKCS10
                RegutilPKCS10 *pkcs10 = malloc(sizeof(RegutilPKCS10));
                pkcs10->keyUsage = pipe_readInt(stdin);
                pkcs10->keySize = pipe_readInt(stdin);
                pkcs10->subjectDN = pipe_readString(stdin);
                pkcs10->includeFullDN = pipe_readInt(stdin);
                
                pkcs10->next = input.pkcs10;
                input.pkcs10 = pkcs10;
            }
            
            // CMC
            input.cmc.oneTimePassword = pipe_readString(stdin);
            input.cmc.rfc2729cmcoid = pipe_readString(stdin);
            
            // Check for broken pipe
            if (feof(stdin)) goto createReq_end;
            
            // Check input
            if (!input.pkcs10) goto createReq_end;
            
            // Get name to display
            name = bankid_getRequestDisplayName(&input);
            if (!name) goto createReq_end;
            
            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) goto createReq_end;
            
            platform_startChoosePassword(name, browserWindowId);
            platform_setPasswordPolicy(input.minPasswordLength,
                                       input.minPasswordNonDigits,
                                       input.minPasswordDigits);
            
            for (;;) {
                error = RUERR_UserCancel;
                // Ask for a password
                if (!platform_choosePassword(password, password_maxsize))
                    break;
                
                // Try to authenticate/sign
                // Generate key pair and construct the request
                TokenError tokenError;
                error = bankid_createRequest(&input, hostname, password,
                                             &request, &tokenError);
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                platform_showError(tokenError);
            }
            
            platform_endChoosePassword();
            
            // Send result
          createReq_end:
            secmem_free_page(password);
            pipe_sendInt(stdout, error);
            
            if (!request) pipe_sendString(stdout, "");
            else {
                pipe_sendString(stdout, request);
                free(request);
            }
            
            pipe_flush(stdout);
            platform_leaveMainloop();
            break;
        }
        case PC_StoreCertificates: {
            char *certs = pipe_readString(stdin);
            
            TokenError tokenError;
            BankIDError error = bankid_storeCertificates(certs, hostname,
                                                         &tokenError);
            if (error != BIDERR_OK) {
                if (prefs_debug_dump) {
                    certutil_dumpCertsP7(certs);
                }
                platform_showError(tokenError);
            }
            
            pipe_sendInt(stdout, error);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        default: {
            fprintf(stderr, BINNAME ": invalid command from pipe\n");
            platform_leaveMainloop();
            break;
        }
    }
}
Esempio n. 5
0
File: pipe.c Progetto: hno/fribid
PipeCommand pipe_readCommand(FILE *in) {
    return pipe_readInt(in);
}